[Spice-commits] 100 commits - Makefile Makefile.objs Makefile.target QMP/README arch_init.c audio/audio.h audio/audio_int.h audio/audio_template.h audio/paaudio.c block/blkverify.c block/nbd.c block/qcow2-cluster.c block/qcow2-refcount.c block/qcow2-snapshot.c block/qcow2.c block/qcow2.h block/raw-posix.c block/vvfat.c blockdev.h bsd-user/main.c bsd-user/qemu.h configure console.c cutils.c darwin-user/qemu.h default-configs/ppc-softmmu.mak default-configs/ppc64-softmmu.mak default-configs/ppcemb-softmmu.mak disas.c docs/blkverify.txt docs/migration.txt exec.c fsdev/qemu-fsdev.c hmp-commands.hx hw/fmopl.c hw/ide hw/mips_fulong2e.c hw/mips_malta.c hw/mipsnet.c hw/pci.c hw/ppc.c hw/ppc.h hw/ppc4xx_devs.c hw/rc4030.c hw/scsi-bus.c hw/scsi-disk.c hw/scsi-generic.c hw/sd.c hw/sysbus.c hw/sysbus.h hw/virtex_ml507.c hw/virtio-9p.c hw/virtio-balloon.c hw/virtio-blk.c hw/xen_backend.h json-parser.c kvm-all.c linux-user/m68k-sim.c linux-user/main.c linux-user/qemu.h monitor.c monitor.h nbd.c n et/tap-bsd.c net/tap-haiku.c osdep.c osdep.h pflib.c pflib.h posix-aio-compat.c qemu-char.h qemu-common.h qemu-config.c qemu-config.h qemu-doc.texi qemu-error.h qemu-img.c qemu-io.c qemu-monitor.hx qemu-nbd.c qemu-options.hx qemu_socket.h qerror.c qerror.h qjson.c qjson.h qmp-commands.hx slirp/slirp.h sysemu.h target-cris/translate.c target-microblaze/translate.c target-ppc/cpu.h target-ppc/helper.c target-ppc/op_helper.c target-ppc/translate_init.c ui/qemu-spice.h ui/spice-core.c ui/spice-display.c ui/spice-display.h ui/spice-input.c ui/vnc-enc-tight.c version.rc vl.c
Gerd Hoffmann
kraxel at kemper.freedesktop.org
Thu Oct 7 00:34:42 PDT 2010
Makefile | 38
Makefile.objs | 7
Makefile.target | 19
QMP/README | 4
arch_init.c | 2
audio/audio.h | 8
audio/audio_int.h | 8
audio/audio_template.h | 4
audio/paaudio.c | 2
block/blkverify.c | 382 +++++
block/nbd.c | 2
block/qcow2-cluster.c | 19
block/qcow2-refcount.c | 13
block/qcow2-snapshot.c | 2
block/qcow2.c | 115 +
block/qcow2.h | 4
block/raw-posix.c | 79 -
block/vvfat.c | 27
blockdev.h | 15
bsd-user/main.c | 6
bsd-user/qemu.h | 2
configure | 122 +
console.c | 6
cutils.c | 50
darwin-user/qemu.h | 2
default-configs/ppc-softmmu.mak | 2
default-configs/ppc64-softmmu.mak | 2
default-configs/ppcemb-softmmu.mak | 2
disas.c | 3
docs/blkverify.txt | 69
docs/migration.txt | 56
exec.c | 13
fsdev/qemu-fsdev.c | 9
hmp-commands.hx | 1216 +++++++++++++++++
hw/fmopl.c | 6
hw/ide/core.c | 4
hw/mips_fulong2e.c | 9
hw/mips_malta.c | 7
hw/mipsnet.c | 2
hw/pci.c | 2
hw/ppc.c | 16
hw/ppc.h | 4
hw/ppc4xx_devs.c | 2
hw/rc4030.c | 5
hw/scsi-bus.c | 3
hw/scsi-disk.c | 10
hw/scsi-generic.c | 21
hw/sd.c | 3
hw/sysbus.c | 3
hw/sysbus.h | 5
hw/virtex_ml507.c | 279 ++++
hw/virtio-9p.c | 10
hw/virtio-balloon.c | 12
hw/virtio-blk.c | 1
hw/xen_backend.h | 2
json-parser.c | 3
kvm-all.c | 12
linux-user/m68k-sim.c | 6
linux-user/main.c | 6
linux-user/qemu.h | 2
monitor.c | 369 +++--
monitor.h | 8
nbd.c | 27
net/tap-bsd.c | 4
net/tap-haiku.c | 61
osdep.c | 23
osdep.h | 35
pflib.c | 213 +++
pflib.h | 20
posix-aio-compat.c | 4
qemu-char.h | 3
qemu-common.h | 22
qemu-config.c | 21
qemu-config.h | 1
qemu-doc.texi | 14
qemu-error.h | 9
qemu-img.c | 2
qemu-io.c | 2
qemu-monitor.hx | 2575 -------------------------------------
qemu-nbd.c | 8
qemu-options.hx | 21
qemu_socket.h | 1
qerror.c | 6
qerror.h | 5
qjson.c | 55
qjson.h | 8
qmp-commands.hx | 1541 ++++++++++++++++++++++
slirp/slirp.h | 6
sysemu.h | 1
target-cris/translate.c | 2
target-microblaze/translate.c | 2
target-ppc/cpu.h | 7
target-ppc/helper.c | 40
target-ppc/op_helper.c | 74 -
target-ppc/translate_init.c | 6
ui/qemu-spice.h | 41
ui/spice-core.c | 189 ++
ui/spice-display.c | 412 +++++
ui/spice-display.h | 69
ui/spice-input.c | 217 +++
ui/vnc-enc-tight.c | 2
version.rc | 28
vl.c | 56
103 files changed, 5883 insertions(+), 3072 deletions(-)
New commits:
commit 4447d609688e75a40a10b559e3b6ae83843e3095
Merge: 48f5704... 869564a...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Oct 5 14:14:19 2010 -0500
Merge remote branch 'spice/submit.6' into staging
Conflicts:
configure
Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
diff --cc Makefile.objs
index 9c13bb3,a3113d8..816194a
--- a/Makefile.objs
+++ b/Makefile.objs
@@@ -87,8 -87,9 +88,10 @@@ common-obj-y += pflib.
common-obj-$(CONFIG_BRLAPI) += baum.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
+common-obj-$(CONFIG_WIN32) += version.o
+ common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o
+
audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
audio-obj-$(CONFIG_SDL) += sdlaudio.o
audio-obj-$(CONFIG_OSS) += ossaudio.o
diff --cc configure
index e0d34fd,695a632..9e65de0
--- a/configure
+++ b/configure
@@@ -15,12 -15,12 +15,14 @@@ TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$
TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
-trap "rm -f $TMPC $TMPO $TMPE ; exit" EXIT INT QUIT TERM
+# NB: do not call "exit" in the trap handler; this is buggy with some shells;
+# see <1285349658-3122-1-git-send-email-loic.minier at linaro.org>
+trap "rm -f $TMPC $TMPO $TMPE" EXIT INT QUIT TERM
+ rm -f config.log
compile_object() {
- $cc $QEMU_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null
+ echo $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log
+ $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log 2>&1
}
compile_prog() {
@@@ -2533,13 -2512,11 +2567,17 @@@ f
if test "$fdatasync" = "yes" ; then
echo "CONFIG_FDATASYNC=y" >> $config_host_mak
fi
+if test "$madvise" = "yes" ; then
+ echo "CONFIG_MADVISE=y" >> $config_host_mak
+fi
+if test "$posix_madvise" = "yes" ; then
+ echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak
+fi
+ if test "$spice" = "yes" ; then
+ echo "CONFIG_SPICE=y" >> $config_host_mak
+ fi
+
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
echo "CONFIG_BSD=y" >> $config_host_mak
commit 48f57044e6a826329ebcac5d5a76d776a14e5d43
Merge: e0c8a79... a18b2ce...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Oct 5 13:54:49 2010 -0500
Merge remote branch 'qmp/for-anthony' into staging
diff --cc qjson.h
index 70d0afb,cd60e0b..65b10ea
--- a/qjson.h
+++ b/qjson.h
@@@ -18,10 -18,12 +18,11 @@@
#include "qobject.h"
#include "qstring.h"
-QObject *qobject_from_json(const char *string);
-QObject *qobject_from_jsonf(const char *string, ...)
- __attribute__((__format__ (__printf__, 1, 2)));
-QObject *qobject_from_jsonv(const char *string, va_list *ap);
+QObject *qobject_from_json(const char *string) GCC_FMT_ATTR(1, 0);
+QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2);
+QObject *qobject_from_jsonv(const char *string, va_list *ap) GCC_FMT_ATTR(1, 0);
QString *qobject_to_json(const QObject *obj);
+ QString *qobject_to_json_pretty(const QObject *obj);
#endif /* QJSON_H */
commit e0c8a796d522b80c21b005a19610829c4be2154f
Author: Stefan Weil <weil at mail.berlios.de>
Date: Fri Sep 24 18:30:35 2010 +0200
linux-user: Fix typo m86k -> m68k
Replace m86k_sim_stat by m68k_sim_stat.
Cc: Riku Voipio <riku.voipio at iki.fi>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
diff --git a/linux-user/m68k-sim.c b/linux-user/m68k-sim.c
index 64d3b23..d5926ee 100644
--- a/linux-user/m68k-sim.c
+++ b/linux-user/m68k-sim.c
@@ -38,7 +38,7 @@
#define SYS_ISATTY 29
#define SYS_LSEEK 199
-struct m86k_sim_stat {
+struct m68k_sim_stat {
uint16_t sim_st_dev;
uint16_t sim_st_ino;
uint32_t sim_st_mode;
@@ -138,10 +138,10 @@ void do_m68k_simcall(CPUM68KState *env, int nr)
{
struct stat s;
int rc;
- struct m86k_sim_stat *p;
+ struct m68k_sim_stat *p;
rc = check_err(env, fstat(ARG(0), &s));
if (rc == 0) {
- p = (struct m86k_sim_stat *)(unsigned long)ARG(1);
+ p = (struct m68k_sim_stat *)(unsigned long)ARG(1);
p->sim_st_dev = tswap16(s.st_dev);
p->sim_st_ino = tswap16(s.st_ino);
p->sim_st_mode = tswap32(s.st_mode);
commit b0cd712cc37bc532b26d9935953cf347e025fc7a
Author: Stefan Weil <weil at mail.berlios.de>
Date: Fri Aug 6 21:53:45 2010 +0200
Fix spelling in comments
multifuction -> multifunction
successfull -> successful.
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
diff --git a/hw/pci.c b/hw/pci.c
index 6d0934d..1280d4d 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -604,7 +604,7 @@ static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)
}
/*
- * multifuction bit is interpreted in two ways as follows.
+ * multifunction bit is interpreted in two ways as follows.
* - all functions must set the bit to 1.
* Example: Intel X53
* - function 0 must set the bit, but the rest function (> 0)
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index 842f1a2..7b862b5 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -128,7 +128,7 @@ static ssize_t handle_aiocb_ioctl(struct qemu_paiocb *aiocb)
/*
* This looks weird, but the aio code only consideres a request
- * successfull if it has written the number full number of bytes.
+ * successful if it has written the number full number of bytes.
*
* Now we overload aio_nbytes as aio_ioctl_cmd for the ioctl command,
* so in fact we return the ioctl command here to make posix_aio_read()
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 971bced..af45edd 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -641,7 +641,7 @@ DEFINE_GRADIENT_FILTER_FUNCTION(32)
/*
* Check if a rectangle is all of the same color. If needSameColor is
* set to non-zero, then also check that its color equals to the
- * *colorPtr value. The result is 1 if the test is successfull, and in
+ * *colorPtr value. The result is 1 if the test is successful, and in
* that case new color will be stored in *colorPtr.
*/
commit dda5336eac4ff7a5393cf516ec87692a7d700978
Author: Stefan Weil <weil at mail.berlios.de>
Date: Sun Aug 1 13:43:18 2010 +0200
docs: Improve documentation
Fix some inconsistencies (tabs and punctuation)
and try to improve grammar and spelling.
Cc: Juan Quintela <quintela at redhat.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
diff --git a/docs/migration.txt b/docs/migration.txt
index 69d5383..4848c1e 100644
--- a/docs/migration.txt
+++ b/docs/migration.txt
@@ -1,21 +1,21 @@
= Migration =
QEMU has code to load/save the state of the guest that it is running.
-This are two complementary operations. Saving the state just does
+These are two complementary operations. Saving the state just does
that, saves the state for each device that the guest is running.
Restoring a guest is just the opposite operation: we need to load the
state of each device.
-For this to work, QEMU has to be launch with the same arguments the
+For this to work, QEMU has to be launched with the same arguments the
two times. I.e. it can only restore the state in one guest that has
the same devices that the one it was saved (this last requirement can
-be relaxed a bit, but for now we can consider that configuration have
+be relaxed a bit, but for now we can consider that configuration has
to be exactly the same).
Once that we are able to save/restore a guest, a new functionality is
requested: migration. This means that QEMU is able to start in one
-machine and being "migrated" to other machine. I.e. being moved to
-other machine.
+machine and being "migrated" to another machine. I.e. being moved to
+another machine.
Next was the "live migration" functionality. This is important
because some guests run with a lot of state (specially RAM), and it
@@ -24,7 +24,7 @@ migration allows the guest to continue running while the state is
transferred. Only while the last part of the state is transferred has
the guest to be stopped. Typically the time that the guest is
unresponsive during live migration is the low hundred of milliseconds
-(notice that this depends on lot of things).
+(notice that this depends on a lot of things).
=== Types of migration ===
@@ -35,9 +35,9 @@ to do migration:
- unix migration: do the migration using unix sockets
- exec migration: do the migration using the stdin/stdout through a process.
- fd migration: do the migration using an file descriptor that is
- passed to QEMU. QEMU don't cares how this file descriptor is opened.
+ passed to QEMU. QEMU doesn't care how this file descriptor is opened.
-All this four migration protocols use the same infrastructure to
+All these four migration protocols use the same infrastructure to
save/restore state devices. This infrastructure is shared with the
savevm/loadvm functionality.
@@ -49,21 +49,21 @@ This is used for RAM and block devices. It is not yet ported to vmstate.
=== What is the common infrastructure ===
QEMU uses a QEMUFile abstraction to be able to do migration. Any type
-of migration that what to use QEMU infrastructure has to create a
+of migration that wants to use QEMU infrastructure has to create a
QEMUFile with:
QEMUFile *qemu_fopen_ops(void *opaque,
- QEMUFilePutBufferFunc *put_buffer,
+ QEMUFilePutBufferFunc *put_buffer,
QEMUFileGetBufferFunc *get_buffer,
QEMUFileCloseFunc *close,
QEMUFileRateLimit *rate_limit,
QEMUFileSetRateLimit *set_rate_limit,
- QEMUFileGetRateLimit *get_rate_limit);
+ QEMUFileGetRateLimit *get_rate_limit);
The functions have the following functionality:
This function writes a chunk of data to a file at the given position.
-The pos argument can be ignored if the file is only being used for
+The pos argument can be ignored if the file is only used for
streaming. The handler should try to write all of the data it can.
typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
@@ -76,18 +76,18 @@ bytes actually read should be returned.
typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf,
int64_t pos, int size);
-Close a file and return an error code
+Close a file and return an error code.
typedef int (QEMUFileCloseFunc)(void *opaque);
-Called to determine if the file has exceeded it's bandwidth allocation. The
+Called to determine if the file has exceeded its bandwidth allocation. The
bandwidth capping is a soft limit, not a hard limit.
typedef int (QEMUFileRateLimit)(void *opaque);
Called to change the current bandwidth allocation. This function must return
the new actual bandwidth. It should be new_rate if everything goes OK, and
-the old rate otherwise
+the old rate otherwise.
typedef size_t (QEMUFileSetRateLimit)(void *opaque, size_t new_rate);
typedef size_t (QEMUFileGetRateLimit)(void *opaque);
@@ -111,8 +111,8 @@ version. When we migrate a device, we save/load the state as a series
of fields. Some times, due to bugs or new functionality, we need to
change the state to store more/different information. We use the
version to identify each time that we do a change. Each version is
-associated with a series of fields saved. The save_state always save
-the state as the newer version. But load_state some times is able to
+associated with a series of fields saved. The save_state always saves
+the state as the newer version. But load_state sometimes is able to
load state from an older version.
=== Legacy way ===
@@ -135,14 +135,14 @@ typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
The important functions for the device state format are the save_state
and load_state. Notice that load_state receives a version_id
-parameter to know what state format is receiving. save_state don't
-have a version_id parameter because it uses always the latest version.
+parameter to know what state format is receiving. save_state doesn't
+have a version_id parameter because it always uses the latest version.
=== VMState ===
The legacy way of saving/loading state of the device had the problem
-that we have to maintain in sync two functions. If we did one change
-in one of them and not on the other, we got a failed migration.
+that we have to maintain two functions in sync. If we did one change
+in one of them and not in the other, we would get a failed migration.
VMState changed the way that state is saved/loaded. Instead of using
a function to save the state and another to load it, it was changed to
@@ -173,7 +173,7 @@ We registered this with:
vmstate_register(NULL, 0, &vmstate_kbd, s);
-Note: talk about how vmstate <-> qdev interact, and what the instance id's mean.
+Note: talk about how vmstate <-> qdev interact, and what the instance ids mean.
You can search for VMSTATE_* macros for lots of types used in QEMU in
hw/hw.h.
@@ -182,7 +182,7 @@ hw/hw.h.
You can see that there are several version fields:
-- version_id: the maximum version_id supported by VMState for that device
+- version_id: the maximum version_id supported by VMState for that device.
- minimum_version_id: the minimum version_id that VMState is able to understand
for that device.
- minimum_version_id_old: For devices that were not able to port to vmstate, we can
@@ -195,7 +195,7 @@ deprecated and will be removed when no more users are left.
=== Massaging functions ===
-Some times, it is not enough to be able to save the state directly
+Sometimes, it is not enough to be able to save the state directly
from one structure, we need to fill the correct values there. One
example is when we are using kvm. Before saving the cpu state, we
need to ask kvm to copy to QEMU the state that it is using. And the
@@ -227,14 +227,14 @@ makes very complicated to fix bugs in stable branches. If we need to
add anything to the state to fix a bug, we have to disable migration
to older versions that don't have that bug-fix (i.e. a new field).
-But some time, that bug-fix is only needed sometimes, not always. For
+But sometimes, that bug-fix is only needed sometimes, not always. For
instance, if the device is in the middle of a DMA operation, it is
using a specific functionality, ....
It is impossible to create a way to make migration from any version to
-any other version to work. But we can do better that only allowing
+any other version to work. But we can do better than only allowing
migration from older versions no newer ones. For that fields that are
-only needed sometimes, we add the idea of subsections. a subsection
+only needed sometimes, we add the idea of subsections. A subsection
is "like" a device vmstate, but with a particularity, it has a Boolean
function that tells if that values are needed to be sent or not. If
this functions returns false, the subsection is not sent.
@@ -266,7 +266,7 @@ const VMStateDescription vmstate_ide_drive_pio_state = {
.fields = (VMStateField []) {
VMSTATE_INT32(req_nb_sectors, IDEState),
VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
- vmstate_info_uint8, uint8_t),
+ vmstate_info_uint8, uint8_t),
VMSTATE_INT32(cur_io_buffer_offset, IDEState),
VMSTATE_INT32(cur_io_buffer_len, IDEState),
VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
commit f66724c99a322ec147b0297cba4334c589883b47
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Jul 15 22:28:02 2010 +0200
Add new user mode option -ignore-environment
An empty environment is sometimes useful in user mode.
The new option provides it for linux-user and bsd-user
(darwin-user still has no environment related options).
The patch also adds the documentation for other
environment related options.
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
diff --git a/bsd-user/main.c b/bsd-user/main.c
index aff9f13..6b12f8b 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -795,6 +795,12 @@ int main(int argc, char **argv)
r = argv[optind++];
if (envlist_setenv(envlist, r) != 0)
usage();
+ } else if (!strcmp(r, "ignore-environment")) {
+ envlist_free(envlist);
+ if ((envlist = envlist_create()) == NULL) {
+ (void) fprintf(stderr, "Unable to allocate envlist\n");
+ exit(1);
+ }
} else if (!strcmp(r, "U")) {
r = argv[optind++];
if (envlist_unsetenv(envlist, r) != 0)
diff --git a/linux-user/main.c b/linux-user/main.c
index 69d050f..dbba8be 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2790,6 +2790,12 @@ int main(int argc, char **argv, char **envp)
r = argv[optind++];
if (envlist_setenv(envlist, r) != 0)
usage();
+ } else if (!strcmp(r, "ignore-environment")) {
+ envlist_free(envlist);
+ if ((envlist = envlist_create()) == NULL) {
+ (void) fprintf(stderr, "Unable to allocate envlist\n");
+ exit(1);
+ }
} else if (!strcmp(r, "U")) {
r = argv[optind++];
if (envlist_unsetenv(envlist, r) != 0)
diff --git a/qemu-doc.texi b/qemu-doc.texi
index d7d760f..c376529 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2186,6 +2186,13 @@ Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
Set the x86 stack size in bytes (default=524288)
@item -cpu model
Select CPU model (-cpu ? for list and additional feature selection)
+ at item -ignore-environment
+Start with an empty environment. Without this option,
+the inital environment is a copy of the caller's environment.
+ at item -E @var{var}=@var{value}
+Set environment @var{var} to @var{value}.
+ at item -U @var{var}
+Remove @var{var} from the environment.
@item -B offset
Offset guest address by the specified number of bytes. This is useful when
the address region required by guest applications is reserved on the host.
@@ -2409,6 +2416,13 @@ Print the help
Set the library root path (default=/)
@item -s size
Set the stack size in bytes (default=524288)
+ at item -ignore-environment
+Start with an empty environment. Without this option,
+the inital environment is a copy of the caller's environment.
+ at item -E @var{var}=@var{value}
+Set environment @var{var} to @var{value}.
+ at item -U @var{var}
+Remove @var{var} from the environment.
@item -bsd type
Set the type of the emulated BSD Operating system. Valid values are
FreeBSD, NetBSD and OpenBSD (default).
commit 999fa40e431626121cdee7d244aadfd0c8f2597b
Author: John Clark <clarkjc at runbox.com>
Date: Tue Oct 5 18:38:55 2010 +0200
ppc: Minor 40x MMU fixes
* Fix swapped reading of tlblo/hi.
* Fix tlb exec permissions
Signed-off-by: John Clark <clarkjc at runbox.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 3bc8a34..edbdd80 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1172,9 +1172,7 @@ static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
case 0x1:
check_perms:
/* Check from TLB entry */
- /* XXX: there is a problem here or in the TLB fill code... */
ctx->prot = tlb->prot;
- ctx->prot |= PAGE_EXEC;
ret = check_prot(ctx->prot, rw, access_type);
if (ret == -2)
env->spr[SPR_40x_ESR] = 0;
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 3e6db85..45f1655 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3929,37 +3929,56 @@ static inline int booke_page_size_to_tlb(target_ulong page_size)
}
/* Helpers for 4xx TLB management */
-target_ulong helper_4xx_tlbre_lo (target_ulong entry)
+#define PPC4XX_TLB_ENTRY_MASK 0x0000003f /* Mask for 64 TLB entries */
+
+#define PPC4XX_TLBHI_V 0x00000040
+#define PPC4XX_TLBHI_E 0x00000020
+#define PPC4XX_TLBHI_SIZE_MIN 0
+#define PPC4XX_TLBHI_SIZE_MAX 7
+#define PPC4XX_TLBHI_SIZE_DEFAULT 1
+#define PPC4XX_TLBHI_SIZE_SHIFT 7
+#define PPC4XX_TLBHI_SIZE_MASK 0x00000007
+
+#define PPC4XX_TLBLO_EX 0x00000200
+#define PPC4XX_TLBLO_WR 0x00000100
+#define PPC4XX_TLBLO_ATTR_MASK 0x000000FF
+#define PPC4XX_TLBLO_RPN_MASK 0xFFFFFC00
+
+target_ulong helper_4xx_tlbre_hi (target_ulong entry)
{
ppcemb_tlb_t *tlb;
target_ulong ret;
int size;
- entry &= 0x3F;
+ entry &= PPC4XX_TLB_ENTRY_MASK;
tlb = &env->tlb[entry].tlbe;
ret = tlb->EPN;
- if (tlb->prot & PAGE_VALID)
- ret |= 0x400;
+ if (tlb->prot & PAGE_VALID) {
+ ret |= PPC4XX_TLBHI_V;
+ }
size = booke_page_size_to_tlb(tlb->size);
- if (size < 0 || size > 0x7)
- size = 1;
- ret |= size << 7;
+ if (size < PPC4XX_TLBHI_SIZE_MIN || size > PPC4XX_TLBHI_SIZE_MAX) {
+ size = PPC4XX_TLBHI_SIZE_DEFAULT;
+ }
+ ret |= size << PPC4XX_TLBHI_SIZE_SHIFT;
env->spr[SPR_40x_PID] = tlb->PID;
return ret;
}
-target_ulong helper_4xx_tlbre_hi (target_ulong entry)
+target_ulong helper_4xx_tlbre_lo (target_ulong entry)
{
ppcemb_tlb_t *tlb;
target_ulong ret;
- entry &= 0x3F;
+ entry &= PPC4XX_TLB_ENTRY_MASK;
tlb = &env->tlb[entry].tlbe;
ret = tlb->RPN;
- if (tlb->prot & PAGE_EXEC)
- ret |= 0x200;
- if (tlb->prot & PAGE_WRITE)
- ret |= 0x100;
+ if (tlb->prot & PAGE_EXEC) {
+ ret |= PPC4XX_TLBLO_EX;
+ }
+ if (tlb->prot & PAGE_WRITE) {
+ ret |= PPC4XX_TLBLO_WR;
+ }
return ret;
}
@@ -3970,30 +3989,32 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val)
LOG_SWTLB("%s entry %d val " TARGET_FMT_lx "\n", __func__, (int)entry,
val);
- entry &= 0x3F;
+ entry &= PPC4XX_TLB_ENTRY_MASK;
tlb = &env->tlb[entry].tlbe;
/* Invalidate previous TLB (if it's valid) */
if (tlb->prot & PAGE_VALID) {
end = tlb->EPN + tlb->size;
LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end "
TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
- for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
+ for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
tlb_flush_page(env, page);
+ }
}
- tlb->size = booke_tlb_to_page_size((val >> 7) & 0x7);
+ tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT)
+ & PPC4XX_TLBHI_SIZE_MASK);
/* We cannot handle TLB size < TARGET_PAGE_SIZE.
* If this ever occurs, one should use the ppcemb target instead
* of the ppc or ppc64 one
*/
- if ((val & 0x40) && tlb->size < TARGET_PAGE_SIZE) {
+ if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) {
cpu_abort(env, "TLB size " TARGET_FMT_lu " < %u "
"are not supported (%d)\n",
tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7));
}
tlb->EPN = val & ~(tlb->size - 1);
- if (val & 0x40) {
+ if (val & PPC4XX_TLBHI_V) {
tlb->prot |= PAGE_VALID;
- if (val & 0x20) {
+ if (val & PPC4XX_TLBHI_E) {
/* XXX: TO BE FIXED */
cpu_abort(env,
"Little-endian TLB entries are not supported by now\n");
@@ -4014,8 +4035,9 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val)
end = tlb->EPN + tlb->size;
LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end "
TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
- for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
+ for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
tlb_flush_page(env, page);
+ }
}
}
@@ -4025,15 +4047,17 @@ void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val)
LOG_SWTLB("%s entry %i val " TARGET_FMT_lx "\n", __func__, (int)entry,
val);
- entry &= 0x3F;
+ entry &= PPC4XX_TLB_ENTRY_MASK;
tlb = &env->tlb[entry].tlbe;
- tlb->attr = val & 0xFF;
- tlb->RPN = val & 0xFFFFFC00;
+ tlb->attr = val & PPC4XX_TLBLO_ATTR_MASK;
+ tlb->RPN = val & PPC4XX_TLBLO_RPN_MASK;
tlb->prot = PAGE_READ;
- if (val & 0x200)
+ if (val & PPC4XX_TLBLO_EX) {
tlb->prot |= PAGE_EXEC;
- if (val & 0x100)
+ }
+ if (val & PPC4XX_TLBLO_WR) {
tlb->prot |= PAGE_WRITE;
+ }
LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx
" size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__,
(int)entry, tlb->RPN, tlb->EPN, tlb->size,
commit 358664cc6d1b5f7c36004be0179b36011b81c49d
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date: Mon Sep 20 14:11:19 2010 +0100
console: Avoid dereferencing NULL active_console
The console_select() function does not check that active_console is
non-NULL before dereferencing it. When invoked with qemu -nodefaults it
is possible to hit this case.
This patch checks that active_console is non-NULL before stashing away
the old console dimensions in console_select().
Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Acked-by: Gerd Hoffmann <kraxel at redhat.com>
Acked-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/console.c b/console.c
index 698bc10..c1728b1 100644
--- a/console.c
+++ b/console.c
@@ -1060,8 +1060,10 @@ void console_select(unsigned int index)
if (index >= MAX_CONSOLES)
return;
- active_console->g_width = ds_get_width(active_console->ds);
- active_console->g_height = ds_get_height(active_console->ds);
+ if (active_console) {
+ active_console->g_width = ds_get_width(active_console->ds);
+ active_console->g_height = ds_get_height(active_console->ds);
+ }
s = consoles[index];
if (s) {
DisplayState *ds = s->ds;
commit 7fd3f494409775b491ca08f9026c45da13852a6d
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Sep 30 22:39:51 2010 +0200
exec: Fix compilation error for debug code
is_softmmu was removed with commit
d4c430a80f000d722bb70287af4d4c184a8d7006,
so remove it now from debug code, too.
Fix also the format specifier for paddr
in the same line of code.
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/exec.c b/exec.c
index 9b5464f..1fbe91c 100644
--- a/exec.c
+++ b/exec.c
@@ -2173,8 +2173,9 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
pd = p->phys_offset;
}
#if defined(DEBUG_TLB)
- printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
- vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
+ printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
+ " prot=%x idx=%d pd=0x%08lx\n",
+ vaddr, paddr, prot, mmu_idx, pd);
#endif
address = vaddr;
commit b832134d8ab6cb455bf182c99e5610803d8d2500
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Sep 30 22:05:42 2010 +0200
rc4030: Fix compilation error in debug code
min was unknown here, so avoid it.
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/rc4030.c b/hw/rc4030.c
index 2231373..abbc3eb 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -749,7 +749,10 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_wri
printf("rc4030 dma: Copying %d bytes %s host %p\n",
len, is_write ? "from" : "to", buf);
for (i = 0; i < len; i += 16) {
- int n = min(16, len - i);
+ int n = 16;
+ if (n > len - i) {
+ n = len - i;
+ }
for (j = 0; j < n; j++)
printf("%02x ", buf[i + j]);
while (j++ < 16)
commit a4a77677d790c07759ae5219110de2e472a6b0a9
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Sep 30 21:33:15 2010 +0200
mipsnet: Fix compiler warning in debug code
size_t needs a different format specifier, so fix this.
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index a95b3ce..c5e54ff 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -81,7 +81,7 @@ static ssize_t mipsnet_receive(VLANClientState *nc, const uint8_t *buf, size_t s
MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
#ifdef DEBUG_MIPSNET_RECEIVE
- printf("mipsnet: receiving len=%d\n", size);
+ printf("mipsnet: receiving len=%zu\n", size);
#endif
if (!mipsnet_can_receive(nc))
return -1;
commit d523d5d69409a2bb3b5a2c53179d190d2a8c06b2
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Sep 30 21:15:39 2010 +0200
block/vvfat: Fix compiler warning in debug code
Fix this compiler warning:
./block/vvfat.c:2285: error: comparison of unsigned expression >= 0 is always true
Cc: Blue Swirl <blauwirbel at gmail.com>
Cc: Kevin Wolf <kwolf at redhat.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/block/vvfat.c b/block/vvfat.c
index 53e57bf..26dd474 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2282,7 +2282,6 @@ static void check1(BDRVVVFATState* s)
fprintf(stderr, "deleted\n");
continue;
}
- assert(mapping->dir_index >= 0);
assert(mapping->dir_index < s->directory.next);
direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
commit c9ba47dc5d8679efa4d5425aa27e0f8132920fb5
Author: Stefan Weil <weil at mail.berlios.de>
Date: Mon Sep 27 18:45:47 2010 +0200
virtio-9p: Use GCC_FMT_ATTR and fix a format warning
With the new gcc format warnings, gcc detected this:
/qemu/hw/virtio-9p.c:1040: error: format â%uâ expects type âunsigned intâ, but argument 4 has type â__nlink_tâ
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 32fa3bc..3b2d49c 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -333,7 +333,8 @@ static int number_to_string(void *arg, char type)
return ret;
}
-static int v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap)
+static int GCC_FMT_ATTR(2, 0)
+v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap)
{
va_list ap2;
char *iter = (char *)fmt;
@@ -387,7 +388,8 @@ alloc_print:
return vsprintf(*strp, fmt, ap);
}
-static void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3)
+v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
{
va_list ap;
int err;
@@ -1034,8 +1036,8 @@ static int stat_to_v9stat(V9fsState *s, V9fsString *name,
S_ISCHR(stbuf->st_mode) ? 'c' : 'b',
major(stbuf->st_rdev), minor(stbuf->st_rdev));
} else if (S_ISDIR(stbuf->st_mode) || S_ISREG(stbuf->st_mode)) {
- v9fs_string_sprintf(&v9stat->extension, "%s %u",
- "HARDLINKCOUNT", stbuf->st_nlink);
+ v9fs_string_sprintf(&v9stat->extension, "%s %lu",
+ "HARDLINKCOUNT", (unsigned long)stbuf->st_nlink);
}
str = strrchr(name->data, '/');
commit 6ea421fee15f5f2d32c2b471cb2336463d4e316b
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Sep 23 20:47:32 2010 +0200
blockdev: Use GCC_FMT_ATTR (format checking)
Additional changes:
* Removed 'extern' from drive_add (avoids too long line).
* Removed 'extern' from other functions (makes declarations
consistent with others in same header file).
Cc: Blue Swirl <blauwirbel at gmail.com>
Cc: Kevin Wolf <kwolf at redhat.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/blockdev.h b/blockdev.h
index 89dcd9a..653affc 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -34,14 +34,13 @@ struct DriveInfo {
#define MAX_IDE_DEVS 2
#define MAX_SCSI_DEVS 7
-extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
-extern int drive_get_max_bus(BlockInterfaceType type);
-extern void drive_uninit(DriveInfo *dinfo);
-extern DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);
-
-extern QemuOpts *drive_add(const char *file, const char *fmt, ...);
-extern DriveInfo *drive_init(QemuOpts *arg, int default_to_scsi,
- int *fatal_error);
+DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
+int drive_get_max_bus(BlockInterfaceType type);
+void drive_uninit(DriveInfo *dinfo);
+DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);
+
+QemuOpts *drive_add(const char *file, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+DriveInfo *drive_init(QemuOpts *arg, int default_to_scsi, int *fatal_error);
/* device-hotplug */
commit 8b7968f7c4ac8c07cad6a1a0891d38cf239a2839
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Sep 23 21:28:05 2010 +0200
Use GCC_FMT_ATTR (format checking)
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/audio/audio.h b/audio/audio.h
index 39a0631..a70fda9 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -86,7 +86,7 @@ typedef struct QEMUAudioTimeStamp {
uint64_t old_ts;
} QEMUAudioTimeStamp;
-void AUD_vlog (const char *cap, const char *fmt, va_list ap);
+void AUD_vlog (const char *cap, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void AUD_help (void);
diff --git a/disas.c b/disas.c
index 79a98de..afe331f 100644
--- a/disas.c
+++ b/disas.c
@@ -349,7 +349,8 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
return 0;
}
-static int monitor_fprintf(FILE *stream, const char *fmt, ...)
+static int GCC_FMT_ATTR(2, 3)
+monitor_fprintf(FILE *stream, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index 61ca9c4..df80ef6 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -76,7 +76,8 @@ static struct _loaderparams {
const char *initrd_filename;
} loaderparams;
-static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
+ const char *string, ...)
{
va_list ap;
int32_t table_addr;
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 1cb7880..0969089 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -654,7 +654,8 @@ static void write_bootloader (CPUState *env, uint8_t *base,
}
-static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
+ const char *string, ...)
{
va_list ap;
int32_t table_addr;
diff --git a/json-parser.c b/json-parser.c
index 70b9b6f..6c06ef9 100644
--- a/json-parser.c
+++ b/json-parser.c
@@ -91,7 +91,8 @@ static int token_is_escape(QObject *obj, const char *value)
/**
* Error handler
*/
-static void parse_error(JSONParserContext *ctxt, QObject *token, const char *msg, ...)
+static void GCC_FMT_ATTR(3, 4) parse_error(JSONParserContext *ctxt,
+ QObject *token, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
diff --git a/monitor.c b/monitor.c
index e602480..377ab37 100644
--- a/monitor.c
+++ b/monitor.c
@@ -316,7 +316,8 @@ void monitor_print_filename(Monitor *mon, const char *filename)
}
}
-static int monitor_fprintf(FILE *stream, const char *fmt, ...)
+static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
+ const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
diff --git a/monitor.h b/monitor.h
index 185cc3e..4a6cf82 100644
--- a/monitor.h
+++ b/monitor.h
@@ -49,7 +49,8 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
int monitor_get_fd(Monitor *mon, const char *fdname);
-void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap);
+void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+ GCC_FMT_ATTR(2, 0);
void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void monitor_print_filename(Monitor *mon, const char *filename);
void monitor_flush(Monitor *mon);
diff --git a/qemu-char.h b/qemu-char.h
index 6ea01ba..18ad12b 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -76,7 +76,8 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
void (*init)(struct CharDriverState *s));
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
void qemu_chr_close(CharDriverState *chr);
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
+void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
void qemu_chr_send_event(CharDriverState *s, int event);
void qemu_chr_add_handlers(CharDriverState *s,
diff --git a/qemu-error.h b/qemu-error.h
index 531ec63..4d5c537 100644
--- a/qemu-error.h
+++ b/qemu-error.h
@@ -30,7 +30,7 @@ void loc_set_none(void);
void loc_set_cmdline(char **argv, int idx, int cnt);
void loc_set_file(const char *fname, int lno);
-void error_vprintf(const char *fmt, va_list ap);
+void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void error_print_loc(void);
diff --git a/qemu-img.c b/qemu-img.c
index 4e035e4..578b8eb 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -39,7 +39,7 @@ typedef struct img_cmd_t {
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
#define BDRV_O_FLAGS BDRV_O_CACHE_WB
-static void error(const char *fmt, ...)
+static void GCC_FMT_ATTR(1, 2) error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
diff --git a/qerror.c b/qerror.c
index 0af3ab3..ac2cdaf 100644
--- a/qerror.c
+++ b/qerror.c
@@ -218,7 +218,8 @@ QError *qerror_new(void)
return qerr;
}
-static void qerror_abort(const QError *qerr, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) qerror_abort(const QError *qerr,
+ const char *fmt, ...)
{
va_list ap;
@@ -233,7 +234,8 @@ static void qerror_abort(const QError *qerr, const char *fmt, ...)
abort();
}
-static void qerror_set_data(QError *qerr, const char *fmt, va_list *va)
+static void GCC_FMT_ATTR(2, 0) qerror_set_data(QError *qerr,
+ const char *fmt, va_list *va)
{
QObject *obj;
diff --git a/qerror.h b/qerror.h
index f2984dd..943a24b 100644
--- a/qerror.h
+++ b/qerror.h
@@ -34,7 +34,7 @@ typedef struct QError {
QError *qerror_new(void);
QError *qerror_from_info(const char *file, int linenr, const char *func,
- const char *fmt, va_list *va);
+ const char *fmt, va_list *va) GCC_FMT_ATTR(4, 0);
QString *qerror_human(const QError *qerror);
void qerror_print(QError *qerror);
void qerror_report_internal(const char *file, int linenr, const char *func,
diff --git a/qjson.h b/qjson.h
index 7eef357..70d0afb 100644
--- a/qjson.h
+++ b/qjson.h
@@ -18,9 +18,9 @@
#include "qobject.h"
#include "qstring.h"
-QObject *qobject_from_json(const char *string);
+QObject *qobject_from_json(const char *string) GCC_FMT_ATTR(1, 0);
QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2);
-QObject *qobject_from_jsonv(const char *string, va_list *ap);
+QObject *qobject_from_jsonv(const char *string, va_list *ap) GCC_FMT_ATTR(1, 0);
QString *qobject_to_json(const QObject *obj);
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 6c7488c..462292d 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -263,7 +263,7 @@ void if_start(struct ttys *);
long gethostid(void);
#endif
-void lprint(const char *, ...);
+void lprint(const char *, ...) GCC_FMT_ATTR(1, 2);
#ifndef _WIN32
#include <netdb.h>
commit e5924d8980e0bd027f2f12fa702ec1c555538230
Author: Stefan Weil <weil at mail.berlios.de>
Date: Thu Sep 23 21:28:03 2010 +0200
Replace most gcc format attributes by macro GCC_FMT_ATTR (format checking)
Since version 4.4.x, gcc supports additional format attributes.
__attribute__ ((format (gnu_printf, 1, 2)))
should be used instead of
__attribute__ ((format (printf, 1, 2))
because QEMU always uses standard format strings (even with mingw32).
The patch replaces format attribute printf / __printf__ by macro
GCC_FMT_ATTR which uses gnu_printf if supported.
It also removes an #ifdef __GNUC__ (not needed any longer).
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/audio/audio.h b/audio/audio.h
index 454ade2..39a0631 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -87,11 +87,7 @@ typedef struct QEMUAudioTimeStamp {
} QEMUAudioTimeStamp;
void AUD_vlog (const char *cap, const char *fmt, va_list ap);
-void AUD_log (const char *cap, const char *fmt, ...)
-#ifdef __GNUC__
- __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
- ;
+void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void AUD_help (void);
void AUD_register_card (const char *name, QEMUSoundCard *card);
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 554ff8b..9763616 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -139,7 +139,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6);
-void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
extern THREAD CPUState *thread_env;
void cpu_loop(CPUState *env);
char *target_strerror(int err);
diff --git a/darwin-user/qemu.h b/darwin-user/qemu.h
index 462bbda..0c5081b 100644
--- a/darwin-user/qemu.h
+++ b/darwin-user/qemu.h
@@ -99,7 +99,7 @@ int do_sigaction(int sig, const struct sigaction *act,
struct sigaction *oact);
int do_sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss);
-void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void qerror(const char *fmt, ...);
void write_dt(void *ptr, unsigned long addr, unsigned long limit, int flags);
diff --git a/hw/xen_backend.h b/hw/xen_backend.h
index 292126d..1b428e3 100644
--- a/hw/xen_backend.h
+++ b/hw/xen_backend.h
@@ -84,7 +84,7 @@ int xen_be_bind_evtchn(struct XenDevice *xendev);
void xen_be_unbind_evtchn(struct XenDevice *xendev);
int xen_be_send_notify(struct XenDevice *xendev);
void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...)
- __attribute__ ((format(printf, 3, 4)));
+ GCC_FMT_ATTR(3, 4);
/* actual backend drivers */
extern struct XenDevOps xen_console_ops; /* xen_console.c */
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 794fe49..708021e 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -186,7 +186,7 @@ void syscall_init(void);
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6);
-void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
extern THREAD CPUState *thread_env;
void cpu_loop(CPUState *env);
char *target_strerror(int err);
diff --git a/monitor.h b/monitor.h
index 38b22a4..185cc3e 100644
--- a/monitor.h
+++ b/monitor.h
@@ -50,8 +50,7 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
int monitor_get_fd(Monitor *mon, const char *fdname);
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap);
-void monitor_printf(Monitor *mon, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
+void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void monitor_print_filename(Monitor *mon, const char *filename);
void monitor_flush(Monitor *mon);
diff --git a/qemu-common.h b/qemu-common.h
index 88c5207..81aafa0 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -196,8 +196,7 @@ int qemu_pipe(int pipefd[2]);
/* Error handling. */
-void QEMU_NORETURN hw_error(const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
+void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/* IO callbacks. */
typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
diff --git a/qemu-error.h b/qemu-error.h
index a45609f..531ec63 100644
--- a/qemu-error.h
+++ b/qemu-error.h
@@ -31,11 +31,10 @@ void loc_set_cmdline(char **argv, int idx, int cnt);
void loc_set_file(const char *fname, int lno);
void error_vprintf(const char *fmt, va_list ap);
-void error_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
-void error_printf_unless_qmp(const char *fmt, ...)
- __attribute__ ((format(printf, 1, 2)));
+void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
+void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void error_print_loc(void);
void error_set_progname(const char *argv0);
-void error_report(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
+void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
#endif
diff --git a/qerror.h b/qerror.h
index 62802ea..f2984dd 100644
--- a/qerror.h
+++ b/qerror.h
@@ -38,8 +38,7 @@ QError *qerror_from_info(const char *file, int linenr, const char *func,
QString *qerror_human(const QError *qerror);
void qerror_print(QError *qerror);
void qerror_report_internal(const char *file, int linenr, const char *func,
- const char *fmt, ...)
- __attribute__ ((format(printf, 4, 5)));
+ const char *fmt, ...) GCC_FMT_ATTR(4, 5);
#define qerror_report(fmt, ...) \
qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
QError *qobject_to_qerror(const QObject *obj);
diff --git a/qjson.h b/qjson.h
index 7afec2e..7eef357 100644
--- a/qjson.h
+++ b/qjson.h
@@ -19,8 +19,7 @@
#include "qstring.h"
QObject *qobject_from_json(const char *string);
-QObject *qobject_from_jsonf(const char *string, ...)
- __attribute__((__format__ (__printf__, 1, 2)));
+QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2);
QObject *qobject_from_jsonv(const char *string, va_list *ap);
QString *qobject_to_json(const QObject *obj);
commit 4a2b39d3232fea40d3e396a683f27f5e378ae46e
Author: Andreas Färber <andreas.faerber at web.de>
Date: Mon Sep 20 00:50:48 2010 +0200
slirp: Silence warning on Haiku
Haiku has O_BINARY in fcntl.h.
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Cc: Jan Kiszka <jan.kiszka at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 3a5d592..6c7488c 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -24,7 +24,9 @@ typedef char *caddr_t;
#else
# define ioctlsocket ioctl
# define closesocket(s) close(s)
-# define O_BINARY 0
+# if !defined(__HAIKU__)
+# define O_BINARY 0
+# endif
#endif
#include <sys/types.h>
commit 3ee66dfa529e36e0dab130ace2abc94f0bd65156
Author: Andreas Färber <andreas.faerber at web.de>
Date: Mon Sep 20 00:50:47 2010 +0200
tap: Add stub for Haiku
Adapted from AIX code.
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/Makefile.objs b/Makefile.objs
index dde3ba9..9c13bb3 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -31,6 +31,7 @@ net-nested-$(CONFIG_WIN32) += tap-win32.o
net-nested-$(CONFIG_BSD) += tap-bsd.o
net-nested-$(CONFIG_SOLARIS) += tap-solaris.o
net-nested-$(CONFIG_AIX) += tap-aix.o
+net-nested-$(CONFIG_HAIKU) += tap-haiku.o
net-nested-$(CONFIG_SLIRP) += slirp.o
net-nested-$(CONFIG_VDE) += vde.o
net-obj-y += $(addprefix net/, $(net-nested-y))
diff --git a/net/tap-haiku.c b/net/tap-haiku.c
new file mode 100644
index 0000000..91dda8e
--- /dev/null
+++ b/net/tap-haiku.c
@@ -0,0 +1,61 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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.
+ */
+
+#include "net/tap.h"
+#include <stdio.h>
+
+int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required)
+{
+ fprintf(stderr, "no tap on Haiku\n");
+ return -1;
+}
+
+int tap_set_sndbuf(int fd, QemuOpts *opts)
+{
+ return 0;
+}
+
+int tap_probe_vnet_hdr(int fd)
+{
+ return 0;
+}
+
+int tap_probe_has_ufo(int fd)
+{
+ return 0;
+}
+
+int tap_probe_vnet_hdr_len(int fd, int len)
+{
+ return 0;
+}
+
+void tap_fd_set_vnet_hdr_len(int fd, int len)
+{
+}
+
+void tap_fd_set_offload(int fd, int csum, int tso4,
+ int tso6, int ecn, int ufo)
+{
+}
commit 5dc2eec957a67fc3250dc437175265636cd36c2a
Author: Andreas Färber <andreas.faerber at web.de>
Date: Mon Sep 20 00:50:46 2010 +0200
nbd: Haiku has _IO() in its BSD compatibility layer
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/nbd.c b/nbd.c
index 4bf2eb7..d8ebc42 100644
--- a/nbd.c
+++ b/nbd.c
@@ -23,7 +23,7 @@
#ifndef _WIN32
#include <sys/ioctl.h>
#endif
-#ifdef __sun__
+#if defined(__sun__) || defined(__HAIKU__)
#include <sys/ioccom.h>
#endif
#include <ctype.h>
commit aff447c9164f23d72154a487c6dac9de001d9f63
Author: Andreas Färber <andreas.faerber at web.de>
Date: Mon Sep 20 00:50:45 2010 +0200
Haiku doesn't have libm
Math functions are integrated into Haiku's libroot.
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/Makefile.target b/Makefile.target
index 91d0381..4b2558a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -31,7 +31,9 @@ endif
PROGS=$(QEMU_PROG)
+ifndef CONFIG_HAIKU
LIBS+=-lm
+endif
kvm.o kvm-all.o vhost.o vhost_net.o: QEMU_CFLAGS+=$(KVM_CFLAGS)
commit bd00d539d36520e8a50821b40c72d3f9311c1fc5
Author: Andreas Färber <andreas.faerber at web.de>
Date: Mon Sep 20 00:50:44 2010 +0200
configure: Don't rely on special pthreads library
Haiku has pthreads integrated into its libroot.so library. No linker arguments
are needed for it, so don't fail if -lpthread and similar don't link.
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/configure b/configure
index 6b086c5..e0d34fd 100755
--- a/configure
+++ b/configure
@@ -1710,13 +1710,17 @@ cat > $TMPC << EOF
#include <pthread.h>
int main(void) { pthread_create(0,0,0,0); return 0; }
EOF
-for pthread_lib in $PTHREADLIBS_LIST; do
- if compile_prog "" "$pthread_lib" ; then
- pthread=yes
- LIBS="$pthread_lib $LIBS"
- break
- fi
-done
+if compile_prog "" "" ; then
+ pthread=yes
+else
+ for pthread_lib in $PTHREADLIBS_LIST; do
+ if compile_prog "" "$pthread_lib" ; then
+ pthread=yes
+ LIBS="$pthread_lib $LIBS"
+ break
+ fi
+ done
+fi
if test "$mingw32" != yes -a "$pthread" = no; then
echo
commit 179cf40000d91ea69f30b7337fa055a775523bf5
Author: Andreas Färber <andreas.faerber>
Date: Mon Sep 20 00:50:43 2010 +0200
configure: Add basic support for Haiku
For compatibility with BeOS, Haiku's error codes are negative whereas recent
POSIX versions require them to be positive. As spotted by François, some
parts of QEMU code rely on this, so use a mapper library to convert them
to positive ones.
Cc: François Revol <revol at free.fr>
Cc: Ingo Weinhold <ingo_weinhold at gmx.de>
Haiku has network functions in libnetwork.so. It doesn't ship libutil.so.
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/configure b/configure
index 8fe4bbe..6b086c5 100755
--- a/configure
+++ b/configure
@@ -319,6 +319,7 @@ io_thread="no"
mixemu="no"
kerneldir=""
aix="no"
+haiku="no"
blobs="yes"
pkgversion=""
check_utests="no"
@@ -336,6 +337,8 @@ elif check_define __OpenBSD__ ; then
targetos='OpenBSD'
elif check_define __sun__ ; then
targetos='SunOS'
+elif check_define __HAIKU__ ; then
+ targetos='Haiku'
else
targetos=`uname -s`
fi
@@ -451,6 +454,11 @@ AIX)
aix="yes"
make="gmake"
;;
+Haiku)
+ haiku="yes"
+ QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS $QEMU_CFLAGS"
+ LIBS="-lposix_error_mapper -lnetwork $LIBS"
+;;
*)
audio_drv_list="oss"
audio_possible_drivers="oss alsa sdl esd pa"
@@ -2030,7 +2038,7 @@ elif compile_prog "" "-lrt" ; then
fi
if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
- "$aix" != "yes" ; then
+ "$aix" != "yes" -a "$haiku" != "yes" ; then
libs_softmmu="-lutil $libs_softmmu"
fi
@@ -2353,6 +2361,9 @@ if test "$solaris" = "yes" ; then
echo "CONFIG_NEEDS_LIBSUNMATH=y" >> $config_host_mak
fi
fi
+if test "$haiku" = "yes" ; then
+ echo "CONFIG_HAIKU=y" >> $config_host_mak
+fi
if test "$static" = "yes" ; then
echo "CONFIG_STATIC=y" >> $config_host_mak
fi
commit a82cdd58fd9ffa8c651f51de8d855f6baf708681
Author: Blue Swirl <blauwirbel at gmail.com>
Date: Sat Oct 2 14:28:12 2010 +0000
trace: avoid unnecessary recompilation if nothing changed
Add logic to detect changes in generated files. If the old
and new files are identical, don't touch the generated file.
This avoids a lot of churn since many files depend on trace.h.
Based on suggestion by Paolo Bonzini.
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/Makefile b/Makefile
index 7c71c83..04ce07d 100644
--- a/Makefile
+++ b/Makefile
@@ -106,11 +106,15 @@ ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
-trace.h: $(SRC_PATH)/trace-events config-host.mak
- $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN $@")
-
-trace.c: $(SRC_PATH)/trace-events config-host.mak
- $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -c < $< > $@," GEN $@")
+trace.h: trace.h-timestamp
+trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
+ $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h")
+ @cmp -s $@ trace.h || cp $@ trace.h
+
+trace.c: trace.c-timestamp
+trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
+ $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c")
+ @cmp -s $@ trace.c || cp $@ trace.c
trace.o: trace.c $(GENERATED_HEADERS)
commit 904fe1fbd10388f384c9930fa2d8a25113b7e7aa
Author: Blue Swirl <blauwirbel at gmail.com>
Date: Sat Oct 2 14:28:08 2010 +0000
Makefile: fix config-devices.mak generation
The logic of detecting changes in default-configs/*.mak is
flawed as can be demonstrated by 'touch default-configs/*.mak'
followed by make. This results in a message claiming that user
made changes to the */config-devices.mak files.
Fix by separating the detection of changes made by the user and
changes in the default-configs.
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/Makefile b/Makefile
index fca1e7a..7c71c83 100644
--- a/Makefile
+++ b/Makefile
@@ -43,9 +43,11 @@ config-all-devices.mak: $(SUBDIR_DEVICES_MAK)
%/config-devices.mak: default-configs/%.mak
$(call quiet-command,cat $< > $@.tmp, " GEN $@")
@if test -f $@; then \
- if cmp -s $@.old $@ || cmp -s $@ $@.tmp; then \
- mv $@.tmp $@; \
- cp -p $@ $@.old; \
+ if cmp -s $@.old $@; then \
+ if ! cmp -s $@ $@.tmp; then \
+ mv $@.tmp $@; \
+ cp -p $@ $@.old; \
+ fi; \
else \
if test -f $@.old; then \
echo "WARNING: $@ (user modified) out of date.";\
commit 3f7132d1a35040331ae4541f010713b835be75e3
Author: Blue Swirl <blauwirbel at gmail.com>
Date: Sat Oct 2 14:27:41 2010 +0000
sysbus: fix address truncation
Fix address truncation in sysbus by using a wider type.
Reported-by: Artyom Tarasenko <atar4qemu at googlemail.com>
Tested-by: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 1f7f138..d817721 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -82,7 +82,8 @@ void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target)
}
}
-void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, int iofunc)
+void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
+ ram_addr_t iofunc)
{
int n;
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 1a8f289..5980901 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -21,7 +21,7 @@ struct SysBusDevice {
target_phys_addr_t addr;
target_phys_addr_t size;
mmio_mapfunc cb;
- int iofunc;
+ ram_addr_t iofunc;
} mmio[QDEV_MAX_MMIO];
};
@@ -39,7 +39,8 @@ typedef struct {
void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init);
void sysbus_register_withprop(SysBusDeviceInfo *info);
void *sysbus_new(void);
-void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, int iofunc);
+void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
+ ram_addr_t iofunc);
void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
mmio_mapfunc cb);
void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
commit 211ecdc0e4226e86c406b0ce91ed355fdde021ab
Author: Stefan Weil <weil at mail.berlios.de>
Date: Sat Oct 2 12:41:03 2010 +0200
target-cris: Use %td for ptrdiff_t arguments in debug message
According to ISO/IEC 9899:1999 7.19.6.1,
the correct length modifier for ptrdiff_t is 't', not 'z'.
Cc: Blue Swirl <blauwirbel at gmail.com>
Cc: Markus Armbruster <armbru at redhat.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 45c7682..8361369 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3409,7 +3409,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
log_target_disas(pc_start, dc->pc - pc_start,
dc->env->pregs[PR_VR]);
- qemu_log("\nisize=%d osize=%zd\n",
+ qemu_log("\nisize=%d osize=%td\n",
dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
}
#endif
commit e6aa0f11edd3251d58bb0e5072aeab9b8713f5c6
Author: Stefan Weil <weil at mail.berlios.de>
Date: Sat Oct 2 12:41:04 2010 +0200
target-microblaze: Use %td for ptrdiff_t arguments in debug message
According to ISO/IEC 9899:1999 7.19.6.1,
the correct length modifier for ptrdiff_t is 't', not 'z'.
Cc: Blue Swirl <blauwirbel at gmail.com>
Cc: Markus Armbruster <armbru at redhat.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 6c305d4..38149bb 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1516,7 +1516,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
#if DISAS_GNU
log_target_disas(pc_start, dc->pc - pc_start, 0);
#endif
- qemu_log("\nisize=%d osize=%zd\n",
+ qemu_log("\nisize=%d osize=%td\n",
dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
}
#endif
commit 3b2e3dc939f289323a3f83b1ad64faa0865bf42b
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date: Sat Oct 2 13:04:49 2010 +0200
virtex: Add braces
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 2af3b81..c5bbeda 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -157,8 +157,9 @@ static int xilinx_load_device_tree(target_phys_addr_t addr,
fdt = load_device_tree(path, &fdt_size);
qemu_free(path);
}
- if (!fdt)
+ if (!fdt) {
return 0;
+ }
}
r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
commit a18b2ce2ed9dc747c2ebab5a220517624e4ff3df
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Fri Sep 10 14:05:23 2010 -0300
QMP/README: Update QMP homepage address
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/QMP/README b/QMP/README
index 7e2b51a..80503f2 100644
--- a/QMP/README
+++ b/QMP/README
@@ -88,4 +88,4 @@ doing any code change. This is so because:
Homepage
--------
-http://www.linux-kvm.org/page/MonitorProtocol
+http://wiki.qemu.org/QMP
commit acd0a09337c51d1cd6861f68add45e94361c8974
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Thu Sep 30 16:00:22 2010 -0300
Monitor: Rename the qemu-monitor.hx file
Let's be consistent and call it hmp-commands.hx, so that we have
qmp-commands.hx for QMP and hmp-commands.hx for HMP.
Please, note that this commit doesn't touch qemu-monitor.texi. All
texi files have the qemu- prefix and I don't think it's worth
changing that.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/Makefile b/Makefile
index 938d88b..3f42fe2 100644
--- a/Makefile
+++ b/Makefile
@@ -249,7 +249,7 @@ TEXIFLAG=$(if $(V),,--quiet)
qemu-options.texi: $(SRC_PATH)/qemu-options.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@")
-qemu-monitor.texi: $(SRC_PATH)/qemu-monitor.hx
+qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@")
QMP/qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx
diff --git a/Makefile.target b/Makefile.target
index 3a1fa7e..518ea27 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -307,7 +307,7 @@ obj-alpha-y = alpha_palcode.o
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
-monitor.o: qemu-monitor.h qmp-commands.h
+monitor.o: hmp-commands.h qmp-commands.h
$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
@@ -328,7 +328,7 @@ $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")
-qemu-monitor.h: $(SRC_PATH)/qemu-monitor.hx
+hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
@@ -337,7 +337,7 @@ qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
clean:
rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
rm -f *.d */*.d tcg/*.o ide/*.o
- rm -f qemu-monitor.h qmp-commands.h gdbstub-xml.c
+ rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
install: all
ifneq ($(PROGS),)
diff --git a/hmp-commands.hx b/hmp-commands.hx
new file mode 100644
index 0000000..81999aa
--- /dev/null
+++ b/hmp-commands.hx
@@ -0,0 +1,1216 @@
+HXCOMM Use DEFHEADING() to define headings in both help text and texi
+HXCOMM Text between STEXI and ETEXI are copied to texi version and
+HXCOMM discarded from C version
+HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
+HXCOMM monitor commands
+HXCOMM HXCOMM can be used for comments, discarded from both texi and C
+
+STEXI
+ at table @option
+ETEXI
+
+ {
+ .name = "help|?",
+ .args_type = "name:s?",
+ .params = "[cmd]",
+ .help = "show the help",
+ .mhandler.cmd = do_help_cmd,
+ },
+
+STEXI
+ at item help or ? [@var{cmd}]
+ at findex help
+Show the help for all commands or just for command @var{cmd}.
+ETEXI
+
+ {
+ .name = "commit",
+ .args_type = "device:B",
+ .params = "device|all",
+ .help = "commit changes to the disk images (if -snapshot is used) or backing files",
+ .mhandler.cmd = do_commit,
+ },
+
+STEXI
+ at item commit
+ at findex commit
+Commit changes to the disk images (if -snapshot is used) or backing files.
+ETEXI
+
+ {
+ .name = "q|quit",
+ .args_type = "",
+ .params = "",
+ .help = "quit the emulator",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_quit,
+ },
+
+STEXI
+ at item q or quit
+ at findex quit
+Quit the emulator.
+ETEXI
+
+ {
+ .name = "eject",
+ .args_type = "force:-f,device:B",
+ .params = "[-f] device",
+ .help = "eject a removable medium (use -f to force it)",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_eject,
+ },
+
+STEXI
+ at item eject [-f] @var{device}
+ at findex eject
+Eject a removable medium (use -f to force it).
+ETEXI
+
+ {
+ .name = "change",
+ .args_type = "device:B,target:F,arg:s?",
+ .params = "device filename [format]",
+ .help = "change a removable medium, optional format",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_change,
+ },
+
+STEXI
+ at item change @var{device} @var{setting}
+ at findex change
+
+Change the configuration of a device.
+
+ at table @option
+ at item change @var{diskdevice} @var{filename} [@var{format}]
+Change the medium for a removable disk device to point to @var{filename}. eg
+
+ at example
+(qemu) change ide1-cd0 /path/to/some.iso
+ at end example
+
+ at var{format} is optional.
+
+ at item change vnc @var{display}, at var{options}
+Change the configuration of the VNC server. The valid syntax for @var{display}
+and @var{options} are described at @ref{sec_invocation}. eg
+
+ at example
+(qemu) change vnc localhost:1
+ at end example
+
+ at item change vnc password [@var{password}]
+
+Change the password associated with the VNC server. If the new password is not
+supplied, the monitor will prompt for it to be entered. VNC passwords are only
+significant up to 8 letters. eg
+
+ at example
+(qemu) change vnc password
+Password: ********
+ at end example
+
+ at end table
+ETEXI
+
+ {
+ .name = "screendump",
+ .args_type = "filename:F",
+ .params = "filename",
+ .help = "save screen into PPM image 'filename'",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_screen_dump,
+ },
+
+STEXI
+ at item screendump @var{filename}
+ at findex screendump
+Save screen into PPM image @var{filename}.
+ETEXI
+
+ {
+ .name = "logfile",
+ .args_type = "filename:F",
+ .params = "filename",
+ .help = "output logs to 'filename'",
+ .mhandler.cmd = do_logfile,
+ },
+
+STEXI
+ at item logfile @var{filename}
+ at findex logfile
+Output logs to @var{filename}.
+ETEXI
+
+#ifdef CONFIG_SIMPLE_TRACE
+ {
+ .name = "trace-event",
+ .args_type = "name:s,option:b",
+ .params = "name on|off",
+ .help = "changes status of a specific trace event",
+ .mhandler.cmd = do_change_trace_event_state,
+ },
+
+STEXI
+ at item trace-event
+ at findex trace-event
+changes status of a trace event
+ETEXI
+
+ {
+ .name = "trace-file",
+ .args_type = "op:s?,arg:F?",
+ .params = "on|off|flush|set [arg]",
+ .help = "open, close, or flush trace file, or set a new file name",
+ .mhandler.cmd = do_trace_file,
+ },
+
+STEXI
+ at item trace-file on|off|flush
+ at findex trace-file
+Open, close, or flush the trace file. If no argument is given, the status of the trace file is displayed.
+ETEXI
+#endif
+
+ {
+ .name = "log",
+ .args_type = "items:s",
+ .params = "item1[,...]",
+ .help = "activate logging of the specified items to '/tmp/qemu.log'",
+ .mhandler.cmd = do_log,
+ },
+
+STEXI
+ at item log @var{item1}[,...]
+ at findex log
+Activate logging of the specified items to @file{/tmp/qemu.log}.
+ETEXI
+
+ {
+ .name = "savevm",
+ .args_type = "name:s?",
+ .params = "[tag|id]",
+ .help = "save a VM snapshot. If no tag or id are provided, a new snapshot is created",
+ .mhandler.cmd = do_savevm,
+ },
+
+STEXI
+ at item savevm [@var{tag}|@var{id}]
+ at findex savevm
+Create a snapshot of the whole virtual machine. If @var{tag} is
+provided, it is used as human readable identifier. If there is already
+a snapshot with the same tag or ID, it is replaced. More info at
+ at ref{vm_snapshots}.
+ETEXI
+
+ {
+ .name = "loadvm",
+ .args_type = "name:s",
+ .params = "tag|id",
+ .help = "restore a VM snapshot from its tag or id",
+ .mhandler.cmd = do_loadvm,
+ },
+
+STEXI
+ at item loadvm @var{tag}|@var{id}
+ at findex loadvm
+Set the whole virtual machine to the snapshot identified by the tag
+ at var{tag} or the unique snapshot ID @var{id}.
+ETEXI
+
+ {
+ .name = "delvm",
+ .args_type = "name:s",
+ .params = "tag|id",
+ .help = "delete a VM snapshot from its tag or id",
+ .mhandler.cmd = do_delvm,
+ },
+
+STEXI
+ at item delvm @var{tag}|@var{id}
+ at findex delvm
+Delete the snapshot identified by @var{tag} or @var{id}.
+ETEXI
+
+ {
+ .name = "singlestep",
+ .args_type = "option:s?",
+ .params = "[on|off]",
+ .help = "run emulation in singlestep mode or switch to normal mode",
+ .mhandler.cmd = do_singlestep,
+ },
+
+STEXI
+ at item singlestep [off]
+ at findex singlestep
+Run the emulation in single step mode.
+If called with option off, the emulation returns to normal mode.
+ETEXI
+
+ {
+ .name = "stop",
+ .args_type = "",
+ .params = "",
+ .help = "stop emulation",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_stop,
+ },
+
+STEXI
+ at item stop
+ at findex stop
+Stop emulation.
+ETEXI
+
+ {
+ .name = "c|cont",
+ .args_type = "",
+ .params = "",
+ .help = "resume emulation",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_cont,
+ },
+
+STEXI
+ at item c or cont
+ at findex cont
+Resume emulation.
+ETEXI
+
+ {
+ .name = "gdbserver",
+ .args_type = "device:s?",
+ .params = "[device]",
+ .help = "start gdbserver on given device (default 'tcp::1234'), stop with 'none'",
+ .mhandler.cmd = do_gdbserver,
+ },
+
+STEXI
+ at item gdbserver [@var{port}]
+ at findex gdbserver
+Start gdbserver session (default @var{port}=1234)
+ETEXI
+
+ {
+ .name = "x",
+ .args_type = "fmt:/,addr:l",
+ .params = "/fmt addr",
+ .help = "virtual memory dump starting at 'addr'",
+ .mhandler.cmd = do_memory_dump,
+ },
+
+STEXI
+ at item x/fmt @var{addr}
+ at findex x
+Virtual memory dump starting at @var{addr}.
+ETEXI
+
+ {
+ .name = "xp",
+ .args_type = "fmt:/,addr:l",
+ .params = "/fmt addr",
+ .help = "physical memory dump starting at 'addr'",
+ .mhandler.cmd = do_physical_memory_dump,
+ },
+
+STEXI
+ at item xp /@var{fmt} @var{addr}
+ at findex xp
+Physical memory dump starting at @var{addr}.
+
+ at var{fmt} is a format which tells the command how to format the
+data. Its syntax is: @option{/@{count@}@{format@}@{size@}}
+
+ at table @var
+ at item count
+is the number of items to be dumped.
+
+ at item format
+can be x (hex), d (signed decimal), u (unsigned decimal), o (octal),
+c (char) or i (asm instruction).
+
+ at item size
+can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
+ at code{h} or @code{w} can be specified with the @code{i} format to
+respectively select 16 or 32 bit code instruction size.
+
+ at end table
+
+Examples:
+ at itemize
+ at item
+Dump 10 instructions at the current instruction pointer:
+ at example
+(qemu) x/10i $eip
+0x90107063: ret
+0x90107064: sti
+0x90107065: lea 0x0(%esi,1),%esi
+0x90107069: lea 0x0(%edi,1),%edi
+0x90107070: ret
+0x90107071: jmp 0x90107080
+0x90107073: nop
+0x90107074: nop
+0x90107075: nop
+0x90107076: nop
+ at end example
+
+ at item
+Dump 80 16 bit values at the start of the video memory.
+ at smallexample
+(qemu) xp/80hx 0xb8000
+0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
+0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
+0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
+0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
+0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
+0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
+0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+ at end smallexample
+ at end itemize
+ETEXI
+
+ {
+ .name = "p|print",
+ .args_type = "fmt:/,val:l",
+ .params = "/fmt expr",
+ .help = "print expression value (use $reg for CPU register access)",
+ .mhandler.cmd = do_print,
+ },
+
+STEXI
+ at item p or print/@var{fmt} @var{expr}
+ at findex print
+
+Print expression value. Only the @var{format} part of @var{fmt} is
+used.
+ETEXI
+
+ {
+ .name = "i",
+ .args_type = "fmt:/,addr:i,index:i.",
+ .params = "/fmt addr",
+ .help = "I/O port read",
+ .mhandler.cmd = do_ioport_read,
+ },
+
+STEXI
+Read I/O port.
+ETEXI
+
+ {
+ .name = "o",
+ .args_type = "fmt:/,addr:i,val:i",
+ .params = "/fmt addr value",
+ .help = "I/O port write",
+ .mhandler.cmd = do_ioport_write,
+ },
+
+STEXI
+Write to I/O port.
+ETEXI
+
+ {
+ .name = "sendkey",
+ .args_type = "string:s,hold_time:i?",
+ .params = "keys [hold_ms]",
+ .help = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)",
+ .mhandler.cmd = do_sendkey,
+ },
+
+STEXI
+ at item sendkey @var{keys}
+ at findex sendkey
+
+Send @var{keys} to the emulator. @var{keys} could be the name of the
+key or @code{#} followed by the raw value in either decimal or hexadecimal
+format. Use @code{-} to press several keys simultaneously. Example:
+ at example
+sendkey ctrl-alt-f1
+ at end example
+
+This command is useful to send keys that your graphical user interface
+intercepts at low level, such as @code{ctrl-alt-f1} in X Window.
+ETEXI
+
+ {
+ .name = "system_reset",
+ .args_type = "",
+ .params = "",
+ .help = "reset the system",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_system_reset,
+ },
+
+STEXI
+ at item system_reset
+ at findex system_reset
+
+Reset the system.
+ETEXI
+
+ {
+ .name = "system_powerdown",
+ .args_type = "",
+ .params = "",
+ .help = "send system power down event",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_system_powerdown,
+ },
+
+STEXI
+ at item system_powerdown
+ at findex system_powerdown
+
+Power down the system (if supported).
+ETEXI
+
+ {
+ .name = "sum",
+ .args_type = "start:i,size:i",
+ .params = "addr size",
+ .help = "compute the checksum of a memory region",
+ .mhandler.cmd = do_sum,
+ },
+
+STEXI
+ at item sum @var{addr} @var{size}
+ at findex sum
+
+Compute the checksum of a memory region.
+ETEXI
+
+ {
+ .name = "usb_add",
+ .args_type = "devname:s",
+ .params = "device",
+ .help = "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')",
+ .mhandler.cmd = do_usb_add,
+ },
+
+STEXI
+ at item usb_add @var{devname}
+ at findex usb_add
+
+Add the USB device @var{devname}. For details of available devices see
+ at ref{usb_devices}
+ETEXI
+
+ {
+ .name = "usb_del",
+ .args_type = "devname:s",
+ .params = "device",
+ .help = "remove USB device 'bus.addr'",
+ .mhandler.cmd = do_usb_del,
+ },
+
+STEXI
+ at item usb_del @var{devname}
+ at findex usb_del
+
+Remove the USB device @var{devname} from the QEMU virtual USB
+hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
+command @code{info usb} to see the devices you can remove.
+ETEXI
+
+ {
+ .name = "device_add",
+ .args_type = "device:O",
+ .params = "driver[,prop=value][,...]",
+ .help = "add device, like -device on the command line",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_device_add,
+ },
+
+STEXI
+ at item device_add @var{config}
+ at findex device_add
+
+Add device.
+ETEXI
+
+ {
+ .name = "device_del",
+ .args_type = "id:s",
+ .params = "device",
+ .help = "remove device",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_device_del,
+ },
+
+STEXI
+ at item device_del @var{id}
+ at findex device_del
+
+Remove device @var{id}.
+ETEXI
+
+ {
+ .name = "cpu",
+ .args_type = "index:i",
+ .params = "index",
+ .help = "set the default CPU",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_cpu_set,
+ },
+
+STEXI
+ at item cpu @var{index}
+ at findex cpu
+Set the default CPU.
+ETEXI
+
+ {
+ .name = "mouse_move",
+ .args_type = "dx_str:s,dy_str:s,dz_str:s?",
+ .params = "dx dy [dz]",
+ .help = "send mouse move events",
+ .mhandler.cmd = do_mouse_move,
+ },
+
+STEXI
+ at item mouse_move @var{dx} @var{dy} [@var{dz}]
+ at findex mouse_move
+Move the active mouse to the specified coordinates @var{dx} @var{dy}
+with optional scroll axis @var{dz}.
+ETEXI
+
+ {
+ .name = "mouse_button",
+ .args_type = "button_state:i",
+ .params = "state",
+ .help = "change mouse button state (1=L, 2=M, 4=R)",
+ .mhandler.cmd = do_mouse_button,
+ },
+
+STEXI
+ at item mouse_button @var{val}
+ at findex mouse_button
+Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
+ETEXI
+
+ {
+ .name = "mouse_set",
+ .args_type = "index:i",
+ .params = "index",
+ .help = "set which mouse device receives events",
+ .mhandler.cmd = do_mouse_set,
+ },
+
+STEXI
+ at item mouse_set @var{index}
+ at findex mouse_set
+Set which mouse device receives events at given @var{index}, index
+can be obtained with
+ at example
+info mice
+ at end example
+ETEXI
+
+#ifdef HAS_AUDIO
+ {
+ .name = "wavcapture",
+ .args_type = "path:F,freq:i?,bits:i?,nchannels:i?",
+ .params = "path [frequency [bits [channels]]]",
+ .help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)",
+ .mhandler.cmd = do_wav_capture,
+ },
+#endif
+STEXI
+ at item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
+ at findex wavcapture
+Capture audio into @var{filename}. Using sample rate @var{frequency}
+bits per sample @var{bits} and number of channels @var{channels}.
+
+Defaults:
+ at itemize @minus
+ at item Sample rate = 44100 Hz - CD quality
+ at item Bits = 16
+ at item Number of channels = 2 - Stereo
+ at end itemize
+ETEXI
+
+#ifdef HAS_AUDIO
+ {
+ .name = "stopcapture",
+ .args_type = "n:i",
+ .params = "capture index",
+ .help = "stop capture",
+ .mhandler.cmd = do_stop_capture,
+ },
+#endif
+STEXI
+ at item stopcapture @var{index}
+ at findex stopcapture
+Stop capture with a given @var{index}, index can be obtained with
+ at example
+info capture
+ at end example
+ETEXI
+
+ {
+ .name = "memsave",
+ .args_type = "val:l,size:i,filename:s",
+ .params = "addr size file",
+ .help = "save to disk virtual memory dump starting at 'addr' of size 'size'",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_memory_save,
+ },
+
+STEXI
+ at item memsave @var{addr} @var{size} @var{file}
+ at findex memsave
+save to disk virtual memory dump starting at @var{addr} of size @var{size}.
+ETEXI
+
+ {
+ .name = "pmemsave",
+ .args_type = "val:l,size:i,filename:s",
+ .params = "addr size file",
+ .help = "save to disk physical memory dump starting at 'addr' of size 'size'",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_physical_memory_save,
+ },
+
+STEXI
+ at item pmemsave @var{addr} @var{size} @var{file}
+ at findex pmemsave
+save to disk physical memory dump starting at @var{addr} of size @var{size}.
+ETEXI
+
+ {
+ .name = "boot_set",
+ .args_type = "bootdevice:s",
+ .params = "bootdevice",
+ .help = "define new values for the boot device list",
+ .mhandler.cmd = do_boot_set,
+ },
+
+STEXI
+ at item boot_set @var{bootdevicelist}
+ at findex boot_set
+
+Define new values for the boot device list. Those values will override
+the values specified on the command line through the @code{-boot} option.
+
+The values that can be specified here depend on the machine type, but are
+the same that can be specified in the @code{-boot} command line option.
+ETEXI
+
+#if defined(TARGET_I386)
+ {
+ .name = "nmi",
+ .args_type = "cpu_index:i",
+ .params = "cpu",
+ .help = "inject an NMI on the given CPU",
+ .mhandler.cmd = do_inject_nmi,
+ },
+#endif
+STEXI
+ at item nmi @var{cpu}
+ at findex nmi
+Inject an NMI on the given CPU (x86 only).
+ETEXI
+
+ {
+ .name = "migrate",
+ .args_type = "detach:-d,blk:-b,inc:-i,uri:s",
+ .params = "[-d] [-b] [-i] uri",
+ .help = "migrate to URI (using -d to not wait for completion)"
+ "\n\t\t\t -b for migration without shared storage with"
+ " full copy of disk\n\t\t\t -i for migration without "
+ "shared storage with incremental copy of disk "
+ "(base image shared between src and destination)",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate,
+ },
+
+
+STEXI
+ at item migrate [-d] [-b] [-i] @var{uri}
+ at findex migrate
+Migrate to @var{uri} (using -d to not wait for completion).
+ -b for migration with full copy of disk
+ -i for migration with incremental copy of disk (base image is shared)
+ETEXI
+
+ {
+ .name = "migrate_cancel",
+ .args_type = "",
+ .params = "",
+ .help = "cancel the current VM migration",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate_cancel,
+ },
+
+STEXI
+ at item migrate_cancel
+ at findex migrate_cancel
+Cancel the current VM migration.
+ETEXI
+
+ {
+ .name = "migrate_set_speed",
+ .args_type = "value:f",
+ .params = "value",
+ .help = "set maximum speed (in bytes) for migrations",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate_set_speed,
+ },
+
+STEXI
+ at item migrate_set_speed @var{value}
+ at findex migrate_set_speed
+Set maximum speed to @var{value} (in bytes) for migrations.
+ETEXI
+
+ {
+ .name = "migrate_set_downtime",
+ .args_type = "value:T",
+ .params = "value",
+ .help = "set maximum tolerated downtime (in seconds) for migrations",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate_set_downtime,
+ },
+
+STEXI
+ at item migrate_set_downtime @var{second}
+ at findex migrate_set_downtime
+Set maximum tolerated downtime (in seconds) for migration.
+ETEXI
+
+#if defined(TARGET_I386)
+ {
+ .name = "drive_add",
+ .args_type = "pci_addr:s,opts:s",
+ .params = "[[<domain>:]<bus>:]<slot>\n"
+ "[file=file][,if=type][,bus=n]\n"
+ "[,unit=m][,media=d][index=i]\n"
+ "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
+ "[snapshot=on|off][,cache=on|off]",
+ .help = "add drive to PCI storage controller",
+ .mhandler.cmd = drive_hot_add,
+ },
+#endif
+
+STEXI
+ at item drive_add
+ at findex drive_add
+Add drive to PCI storage controller.
+ETEXI
+
+#if defined(TARGET_I386)
+ {
+ .name = "pci_add",
+ .args_type = "pci_addr:s,type:s,opts:s?",
+ .params = "auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...",
+ .help = "hot-add PCI device",
+ .mhandler.cmd = pci_device_hot_add,
+ },
+#endif
+
+STEXI
+ at item pci_add
+ at findex pci_add
+Hot-add PCI device.
+ETEXI
+
+#if defined(TARGET_I386)
+ {
+ .name = "pci_del",
+ .args_type = "pci_addr:s",
+ .params = "[[<domain>:]<bus>:]<slot>",
+ .help = "hot remove PCI device",
+ .mhandler.cmd = do_pci_device_hot_remove,
+ },
+#endif
+
+STEXI
+ at item pci_del
+ at findex pci_del
+Hot remove PCI device.
+ETEXI
+
+ {
+ .name = "host_net_add",
+ .args_type = "device:s,opts:s?",
+ .params = "tap|user|socket|vde|dump [options]",
+ .help = "add host VLAN client",
+ .mhandler.cmd = net_host_device_add,
+ },
+
+STEXI
+ at item host_net_add
+ at findex host_net_add
+Add host VLAN client.
+ETEXI
+
+ {
+ .name = "host_net_remove",
+ .args_type = "vlan_id:i,device:s",
+ .params = "vlan_id name",
+ .help = "remove host VLAN client",
+ .mhandler.cmd = net_host_device_remove,
+ },
+
+STEXI
+ at item host_net_remove
+ at findex host_net_remove
+Remove host VLAN client.
+ETEXI
+
+ {
+ .name = "netdev_add",
+ .args_type = "netdev:O",
+ .params = "[user|tap|socket],id=str[,prop=value][,...]",
+ .help = "add host network device",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_netdev_add,
+ },
+
+STEXI
+ at item netdev_add
+ at findex netdev_add
+Add host network device.
+ETEXI
+
+ {
+ .name = "netdev_del",
+ .args_type = "id:s",
+ .params = "id",
+ .help = "remove host network device",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_netdev_del,
+ },
+
+STEXI
+ at item netdev_del
+ at findex netdev_del
+Remove host network device.
+ETEXI
+
+#ifdef CONFIG_SLIRP
+ {
+ .name = "hostfwd_add",
+ .args_type = "arg1:s,arg2:s?,arg3:s?",
+ .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
+ .help = "redirect TCP or UDP connections from host to guest (requires -net user)",
+ .mhandler.cmd = net_slirp_hostfwd_add,
+ },
+#endif
+STEXI
+ at item hostfwd_add
+ at findex hostfwd_add
+Redirect TCP or UDP connections from host to guest (requires -net user).
+ETEXI
+
+#ifdef CONFIG_SLIRP
+ {
+ .name = "hostfwd_remove",
+ .args_type = "arg1:s,arg2:s?,arg3:s?",
+ .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
+ .help = "remove host-to-guest TCP or UDP redirection",
+ .mhandler.cmd = net_slirp_hostfwd_remove,
+ },
+
+#endif
+STEXI
+ at item hostfwd_remove
+ at findex hostfwd_remove
+Remove host-to-guest TCP or UDP redirection.
+ETEXI
+
+ {
+ .name = "balloon",
+ .args_type = "value:M",
+ .params = "target",
+ .help = "request VM to change its memory allocation (in MB)",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_async = do_balloon,
+ .flags = MONITOR_CMD_ASYNC,
+ },
+
+STEXI
+ at item balloon @var{value}
+ at findex balloon
+Request VM to change its memory allocation to @var{value} (in MB).
+ETEXI
+
+ {
+ .name = "set_link",
+ .args_type = "name:s,up:b",
+ .params = "name on|off",
+ .help = "change the link status of a network adapter",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_set_link,
+ },
+
+STEXI
+ at item set_link @var{name} [on|off]
+ at findex set_link
+Switch link @var{name} on (i.e. up) or off (i.e. down).
+ETEXI
+
+ {
+ .name = "watchdog_action",
+ .args_type = "action:s",
+ .params = "[reset|shutdown|poweroff|pause|debug|none]",
+ .help = "change watchdog action",
+ .mhandler.cmd = do_watchdog_action,
+ },
+
+STEXI
+ at item watchdog_action
+ at findex watchdog_action
+Change watchdog action.
+ETEXI
+
+ {
+ .name = "acl_show",
+ .args_type = "aclname:s",
+ .params = "aclname",
+ .help = "list rules in the access control list",
+ .mhandler.cmd = do_acl_show,
+ },
+
+STEXI
+ at item acl_show @var{aclname}
+ at findex acl_show
+List all the matching rules in the access control list, and the default
+policy. There are currently two named access control lists,
+ at var{vnc.x509dname} and @var{vnc.username} matching on the x509 client
+certificate distinguished name, and SASL username respectively.
+ETEXI
+
+ {
+ .name = "acl_policy",
+ .args_type = "aclname:s,policy:s",
+ .params = "aclname allow|deny",
+ .help = "set default access control list policy",
+ .mhandler.cmd = do_acl_policy,
+ },
+
+STEXI
+ at item acl_policy @var{aclname} @code{allow|deny}
+ at findex acl_policy
+Set the default access control list policy, used in the event that
+none of the explicit rules match. The default policy at startup is
+always @code{deny}.
+ETEXI
+
+ {
+ .name = "acl_add",
+ .args_type = "aclname:s,match:s,policy:s,index:i?",
+ .params = "aclname match allow|deny [index]",
+ .help = "add a match rule to the access control list",
+ .mhandler.cmd = do_acl_add,
+ },
+
+STEXI
+ at item acl_add @var{aclname} @var{match} @code{allow|deny} [@var{index}]
+ at findex acl_add
+Add a match rule to the access control list, allowing or denying access.
+The match will normally be an exact username or x509 distinguished name,
+but can optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to
+allow all users in the @code{EXAMPLE.COM} kerberos realm. The match will
+normally be appended to the end of the ACL, but can be inserted
+earlier in the list if the optional @var{index} parameter is supplied.
+ETEXI
+
+ {
+ .name = "acl_remove",
+ .args_type = "aclname:s,match:s",
+ .params = "aclname match",
+ .help = "remove a match rule from the access control list",
+ .mhandler.cmd = do_acl_remove,
+ },
+
+STEXI
+ at item acl_remove @var{aclname} @var{match}
+ at findex acl_remove
+Remove the specified match rule from the access control list.
+ETEXI
+
+ {
+ .name = "acl_reset",
+ .args_type = "aclname:s",
+ .params = "aclname",
+ .help = "reset the access control list",
+ .mhandler.cmd = do_acl_reset,
+ },
+
+STEXI
+ at item acl_reset @var{aclname}
+ at findex acl_reset
+Remove all matches from the access control list, and set the default
+policy back to @code{deny}.
+ETEXI
+
+#if defined(TARGET_I386)
+
+ {
+ .name = "mce",
+ .args_type = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
+ .params = "cpu bank status mcgstatus addr misc",
+ .help = "inject a MCE on the given CPU",
+ .mhandler.cmd = do_inject_mce,
+ },
+
+#endif
+STEXI
+ at item mce @var{cpu} @var{bank} @var{status} @var{mcgstatus} @var{addr} @var{misc}
+ at findex mce (x86)
+Inject an MCE on the given CPU (x86 only).
+ETEXI
+
+ {
+ .name = "getfd",
+ .args_type = "fdname:s",
+ .params = "getfd name",
+ .help = "receive a file descriptor via SCM rights and assign it a name",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_getfd,
+ },
+
+STEXI
+ at item getfd @var{fdname}
+ at findex getfd
+If a file descriptor is passed alongside this command using the SCM_RIGHTS
+mechanism on unix sockets, it is stored using the name @var{fdname} for
+later use by other monitor commands.
+ETEXI
+
+ {
+ .name = "closefd",
+ .args_type = "fdname:s",
+ .params = "closefd name",
+ .help = "close a file descriptor previously passed via SCM rights",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_closefd,
+ },
+
+STEXI
+ at item closefd @var{fdname}
+ at findex closefd
+Close the file descriptor previously assigned to @var{fdname} using the
+ at code{getfd} command. This is only needed if the file descriptor was never
+used by another monitor command.
+ETEXI
+
+ {
+ .name = "block_passwd",
+ .args_type = "device:B,password:s",
+ .params = "block_passwd device password",
+ .help = "set the password of encrypted block devices",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_block_set_passwd,
+ },
+
+STEXI
+ at item block_passwd @var{device} @var{password}
+ at findex block_passwd
+Set the encrypted device @var{device} password to @var{password}
+ETEXI
+
+ {
+ .name = "info",
+ .args_type = "item:s?",
+ .params = "[subcommand]",
+ .help = "show various information about the system state",
+ .mhandler.cmd = do_info,
+ },
+
+STEXI
+ at item info @var{subcommand}
+ at findex info
+Show various information about the system state.
+
+ at table @option
+ at item info version
+show the version of QEMU
+ at item info network
+show the various VLANs and the associated devices
+ at item info chardev
+show the character devices
+ at item info block
+show the block devices
+ at item info blockstats
+show block device statistics
+ at item info registers
+show the cpu registers
+ at item info cpus
+show infos for each CPU
+ at item info history
+show the command line history
+ at item info irq
+show the interrupts statistics (if available)
+ at item info pic
+show i8259 (PIC) state
+ at item info pci
+show emulated PCI device info
+ at item info tlb
+show virtual to physical memory mappings (i386 only)
+ at item info mem
+show the active virtual memory mappings (i386 only)
+ at item info jit
+show dynamic compiler info
+ at item info kvm
+show KVM information
+ at item info numa
+show NUMA information
+ at item info kvm
+show KVM information
+ at item info usb
+show USB devices plugged on the virtual USB hub
+ at item info usbhost
+show all USB host devices
+ at item info profile
+show profiling information
+ at item info capture
+show information about active capturing
+ at item info snapshots
+show list of VM snapshots
+ at item info status
+show the current VM status (running|paused)
+ at item info pcmcia
+show guest PCMCIA status
+ at item info mice
+show which guest mouse is receiving events
+ at item info vnc
+show the vnc server status
+ at item info name
+show the current VM name
+ at item info uuid
+show the current VM UUID
+ at item info cpustats
+show CPU statistics
+ at item info usernet
+show user network stack connection states
+ at item info migrate
+show migration status
+ at item info balloon
+show balloon information
+ at item info qtree
+show device tree
+ at item info qdm
+show qdev device model list
+ at item info roms
+show roms
+ at end table
+ETEXI
+
+#ifdef CONFIG_SIMPLE_TRACE
+STEXI
+ at item info trace
+show contents of trace buffer
+ at item info trace-events
+show available trace events and their state
+ETEXI
+#endif
+
+STEXI
+ at end table
+ETEXI
diff --git a/monitor.c b/monitor.c
index 3f3c9bf..4148dd9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2332,11 +2332,11 @@ int monitor_get_fd(Monitor *mon, const char *fdname)
}
static const mon_cmd_t mon_cmds[] = {
-#include "qemu-monitor.h"
+#include "hmp-commands.h"
{ NULL, NULL, },
};
-/* Please update qemu-monitor.hx when adding or changing commands */
+/* Please update hmp-commands.hx when adding or changing commands */
static const mon_cmd_t info_cmds[] = {
{
.name = "version",
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
deleted file mode 100644
index 81999aa..0000000
--- a/qemu-monitor.hx
+++ /dev/null
@@ -1,1216 +0,0 @@
-HXCOMM Use DEFHEADING() to define headings in both help text and texi
-HXCOMM Text between STEXI and ETEXI are copied to texi version and
-HXCOMM discarded from C version
-HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
-HXCOMM monitor commands
-HXCOMM HXCOMM can be used for comments, discarded from both texi and C
-
-STEXI
- at table @option
-ETEXI
-
- {
- .name = "help|?",
- .args_type = "name:s?",
- .params = "[cmd]",
- .help = "show the help",
- .mhandler.cmd = do_help_cmd,
- },
-
-STEXI
- at item help or ? [@var{cmd}]
- at findex help
-Show the help for all commands or just for command @var{cmd}.
-ETEXI
-
- {
- .name = "commit",
- .args_type = "device:B",
- .params = "device|all",
- .help = "commit changes to the disk images (if -snapshot is used) or backing files",
- .mhandler.cmd = do_commit,
- },
-
-STEXI
- at item commit
- at findex commit
-Commit changes to the disk images (if -snapshot is used) or backing files.
-ETEXI
-
- {
- .name = "q|quit",
- .args_type = "",
- .params = "",
- .help = "quit the emulator",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_quit,
- },
-
-STEXI
- at item q or quit
- at findex quit
-Quit the emulator.
-ETEXI
-
- {
- .name = "eject",
- .args_type = "force:-f,device:B",
- .params = "[-f] device",
- .help = "eject a removable medium (use -f to force it)",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_eject,
- },
-
-STEXI
- at item eject [-f] @var{device}
- at findex eject
-Eject a removable medium (use -f to force it).
-ETEXI
-
- {
- .name = "change",
- .args_type = "device:B,target:F,arg:s?",
- .params = "device filename [format]",
- .help = "change a removable medium, optional format",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_change,
- },
-
-STEXI
- at item change @var{device} @var{setting}
- at findex change
-
-Change the configuration of a device.
-
- at table @option
- at item change @var{diskdevice} @var{filename} [@var{format}]
-Change the medium for a removable disk device to point to @var{filename}. eg
-
- at example
-(qemu) change ide1-cd0 /path/to/some.iso
- at end example
-
- at var{format} is optional.
-
- at item change vnc @var{display}, at var{options}
-Change the configuration of the VNC server. The valid syntax for @var{display}
-and @var{options} are described at @ref{sec_invocation}. eg
-
- at example
-(qemu) change vnc localhost:1
- at end example
-
- at item change vnc password [@var{password}]
-
-Change the password associated with the VNC server. If the new password is not
-supplied, the monitor will prompt for it to be entered. VNC passwords are only
-significant up to 8 letters. eg
-
- at example
-(qemu) change vnc password
-Password: ********
- at end example
-
- at end table
-ETEXI
-
- {
- .name = "screendump",
- .args_type = "filename:F",
- .params = "filename",
- .help = "save screen into PPM image 'filename'",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_screen_dump,
- },
-
-STEXI
- at item screendump @var{filename}
- at findex screendump
-Save screen into PPM image @var{filename}.
-ETEXI
-
- {
- .name = "logfile",
- .args_type = "filename:F",
- .params = "filename",
- .help = "output logs to 'filename'",
- .mhandler.cmd = do_logfile,
- },
-
-STEXI
- at item logfile @var{filename}
- at findex logfile
-Output logs to @var{filename}.
-ETEXI
-
-#ifdef CONFIG_SIMPLE_TRACE
- {
- .name = "trace-event",
- .args_type = "name:s,option:b",
- .params = "name on|off",
- .help = "changes status of a specific trace event",
- .mhandler.cmd = do_change_trace_event_state,
- },
-
-STEXI
- at item trace-event
- at findex trace-event
-changes status of a trace event
-ETEXI
-
- {
- .name = "trace-file",
- .args_type = "op:s?,arg:F?",
- .params = "on|off|flush|set [arg]",
- .help = "open, close, or flush trace file, or set a new file name",
- .mhandler.cmd = do_trace_file,
- },
-
-STEXI
- at item trace-file on|off|flush
- at findex trace-file
-Open, close, or flush the trace file. If no argument is given, the status of the trace file is displayed.
-ETEXI
-#endif
-
- {
- .name = "log",
- .args_type = "items:s",
- .params = "item1[,...]",
- .help = "activate logging of the specified items to '/tmp/qemu.log'",
- .mhandler.cmd = do_log,
- },
-
-STEXI
- at item log @var{item1}[,...]
- at findex log
-Activate logging of the specified items to @file{/tmp/qemu.log}.
-ETEXI
-
- {
- .name = "savevm",
- .args_type = "name:s?",
- .params = "[tag|id]",
- .help = "save a VM snapshot. If no tag or id are provided, a new snapshot is created",
- .mhandler.cmd = do_savevm,
- },
-
-STEXI
- at item savevm [@var{tag}|@var{id}]
- at findex savevm
-Create a snapshot of the whole virtual machine. If @var{tag} is
-provided, it is used as human readable identifier. If there is already
-a snapshot with the same tag or ID, it is replaced. More info at
- at ref{vm_snapshots}.
-ETEXI
-
- {
- .name = "loadvm",
- .args_type = "name:s",
- .params = "tag|id",
- .help = "restore a VM snapshot from its tag or id",
- .mhandler.cmd = do_loadvm,
- },
-
-STEXI
- at item loadvm @var{tag}|@var{id}
- at findex loadvm
-Set the whole virtual machine to the snapshot identified by the tag
- at var{tag} or the unique snapshot ID @var{id}.
-ETEXI
-
- {
- .name = "delvm",
- .args_type = "name:s",
- .params = "tag|id",
- .help = "delete a VM snapshot from its tag or id",
- .mhandler.cmd = do_delvm,
- },
-
-STEXI
- at item delvm @var{tag}|@var{id}
- at findex delvm
-Delete the snapshot identified by @var{tag} or @var{id}.
-ETEXI
-
- {
- .name = "singlestep",
- .args_type = "option:s?",
- .params = "[on|off]",
- .help = "run emulation in singlestep mode or switch to normal mode",
- .mhandler.cmd = do_singlestep,
- },
-
-STEXI
- at item singlestep [off]
- at findex singlestep
-Run the emulation in single step mode.
-If called with option off, the emulation returns to normal mode.
-ETEXI
-
- {
- .name = "stop",
- .args_type = "",
- .params = "",
- .help = "stop emulation",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_stop,
- },
-
-STEXI
- at item stop
- at findex stop
-Stop emulation.
-ETEXI
-
- {
- .name = "c|cont",
- .args_type = "",
- .params = "",
- .help = "resume emulation",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_cont,
- },
-
-STEXI
- at item c or cont
- at findex cont
-Resume emulation.
-ETEXI
-
- {
- .name = "gdbserver",
- .args_type = "device:s?",
- .params = "[device]",
- .help = "start gdbserver on given device (default 'tcp::1234'), stop with 'none'",
- .mhandler.cmd = do_gdbserver,
- },
-
-STEXI
- at item gdbserver [@var{port}]
- at findex gdbserver
-Start gdbserver session (default @var{port}=1234)
-ETEXI
-
- {
- .name = "x",
- .args_type = "fmt:/,addr:l",
- .params = "/fmt addr",
- .help = "virtual memory dump starting at 'addr'",
- .mhandler.cmd = do_memory_dump,
- },
-
-STEXI
- at item x/fmt @var{addr}
- at findex x
-Virtual memory dump starting at @var{addr}.
-ETEXI
-
- {
- .name = "xp",
- .args_type = "fmt:/,addr:l",
- .params = "/fmt addr",
- .help = "physical memory dump starting at 'addr'",
- .mhandler.cmd = do_physical_memory_dump,
- },
-
-STEXI
- at item xp /@var{fmt} @var{addr}
- at findex xp
-Physical memory dump starting at @var{addr}.
-
- at var{fmt} is a format which tells the command how to format the
-data. Its syntax is: @option{/@{count@}@{format@}@{size@}}
-
- at table @var
- at item count
-is the number of items to be dumped.
-
- at item format
-can be x (hex), d (signed decimal), u (unsigned decimal), o (octal),
-c (char) or i (asm instruction).
-
- at item size
-can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
- at code{h} or @code{w} can be specified with the @code{i} format to
-respectively select 16 or 32 bit code instruction size.
-
- at end table
-
-Examples:
- at itemize
- at item
-Dump 10 instructions at the current instruction pointer:
- at example
-(qemu) x/10i $eip
-0x90107063: ret
-0x90107064: sti
-0x90107065: lea 0x0(%esi,1),%esi
-0x90107069: lea 0x0(%edi,1),%edi
-0x90107070: ret
-0x90107071: jmp 0x90107080
-0x90107073: nop
-0x90107074: nop
-0x90107075: nop
-0x90107076: nop
- at end example
-
- at item
-Dump 80 16 bit values at the start of the video memory.
- at smallexample
-(qemu) xp/80hx 0xb8000
-0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
-0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
-0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
-0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
-0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
-0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
-0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
- at end smallexample
- at end itemize
-ETEXI
-
- {
- .name = "p|print",
- .args_type = "fmt:/,val:l",
- .params = "/fmt expr",
- .help = "print expression value (use $reg for CPU register access)",
- .mhandler.cmd = do_print,
- },
-
-STEXI
- at item p or print/@var{fmt} @var{expr}
- at findex print
-
-Print expression value. Only the @var{format} part of @var{fmt} is
-used.
-ETEXI
-
- {
- .name = "i",
- .args_type = "fmt:/,addr:i,index:i.",
- .params = "/fmt addr",
- .help = "I/O port read",
- .mhandler.cmd = do_ioport_read,
- },
-
-STEXI
-Read I/O port.
-ETEXI
-
- {
- .name = "o",
- .args_type = "fmt:/,addr:i,val:i",
- .params = "/fmt addr value",
- .help = "I/O port write",
- .mhandler.cmd = do_ioport_write,
- },
-
-STEXI
-Write to I/O port.
-ETEXI
-
- {
- .name = "sendkey",
- .args_type = "string:s,hold_time:i?",
- .params = "keys [hold_ms]",
- .help = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)",
- .mhandler.cmd = do_sendkey,
- },
-
-STEXI
- at item sendkey @var{keys}
- at findex sendkey
-
-Send @var{keys} to the emulator. @var{keys} could be the name of the
-key or @code{#} followed by the raw value in either decimal or hexadecimal
-format. Use @code{-} to press several keys simultaneously. Example:
- at example
-sendkey ctrl-alt-f1
- at end example
-
-This command is useful to send keys that your graphical user interface
-intercepts at low level, such as @code{ctrl-alt-f1} in X Window.
-ETEXI
-
- {
- .name = "system_reset",
- .args_type = "",
- .params = "",
- .help = "reset the system",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_system_reset,
- },
-
-STEXI
- at item system_reset
- at findex system_reset
-
-Reset the system.
-ETEXI
-
- {
- .name = "system_powerdown",
- .args_type = "",
- .params = "",
- .help = "send system power down event",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_system_powerdown,
- },
-
-STEXI
- at item system_powerdown
- at findex system_powerdown
-
-Power down the system (if supported).
-ETEXI
-
- {
- .name = "sum",
- .args_type = "start:i,size:i",
- .params = "addr size",
- .help = "compute the checksum of a memory region",
- .mhandler.cmd = do_sum,
- },
-
-STEXI
- at item sum @var{addr} @var{size}
- at findex sum
-
-Compute the checksum of a memory region.
-ETEXI
-
- {
- .name = "usb_add",
- .args_type = "devname:s",
- .params = "device",
- .help = "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')",
- .mhandler.cmd = do_usb_add,
- },
-
-STEXI
- at item usb_add @var{devname}
- at findex usb_add
-
-Add the USB device @var{devname}. For details of available devices see
- at ref{usb_devices}
-ETEXI
-
- {
- .name = "usb_del",
- .args_type = "devname:s",
- .params = "device",
- .help = "remove USB device 'bus.addr'",
- .mhandler.cmd = do_usb_del,
- },
-
-STEXI
- at item usb_del @var{devname}
- at findex usb_del
-
-Remove the USB device @var{devname} from the QEMU virtual USB
-hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
-command @code{info usb} to see the devices you can remove.
-ETEXI
-
- {
- .name = "device_add",
- .args_type = "device:O",
- .params = "driver[,prop=value][,...]",
- .help = "add device, like -device on the command line",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_device_add,
- },
-
-STEXI
- at item device_add @var{config}
- at findex device_add
-
-Add device.
-ETEXI
-
- {
- .name = "device_del",
- .args_type = "id:s",
- .params = "device",
- .help = "remove device",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_device_del,
- },
-
-STEXI
- at item device_del @var{id}
- at findex device_del
-
-Remove device @var{id}.
-ETEXI
-
- {
- .name = "cpu",
- .args_type = "index:i",
- .params = "index",
- .help = "set the default CPU",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_cpu_set,
- },
-
-STEXI
- at item cpu @var{index}
- at findex cpu
-Set the default CPU.
-ETEXI
-
- {
- .name = "mouse_move",
- .args_type = "dx_str:s,dy_str:s,dz_str:s?",
- .params = "dx dy [dz]",
- .help = "send mouse move events",
- .mhandler.cmd = do_mouse_move,
- },
-
-STEXI
- at item mouse_move @var{dx} @var{dy} [@var{dz}]
- at findex mouse_move
-Move the active mouse to the specified coordinates @var{dx} @var{dy}
-with optional scroll axis @var{dz}.
-ETEXI
-
- {
- .name = "mouse_button",
- .args_type = "button_state:i",
- .params = "state",
- .help = "change mouse button state (1=L, 2=M, 4=R)",
- .mhandler.cmd = do_mouse_button,
- },
-
-STEXI
- at item mouse_button @var{val}
- at findex mouse_button
-Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
-ETEXI
-
- {
- .name = "mouse_set",
- .args_type = "index:i",
- .params = "index",
- .help = "set which mouse device receives events",
- .mhandler.cmd = do_mouse_set,
- },
-
-STEXI
- at item mouse_set @var{index}
- at findex mouse_set
-Set which mouse device receives events at given @var{index}, index
-can be obtained with
- at example
-info mice
- at end example
-ETEXI
-
-#ifdef HAS_AUDIO
- {
- .name = "wavcapture",
- .args_type = "path:F,freq:i?,bits:i?,nchannels:i?",
- .params = "path [frequency [bits [channels]]]",
- .help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)",
- .mhandler.cmd = do_wav_capture,
- },
-#endif
-STEXI
- at item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
- at findex wavcapture
-Capture audio into @var{filename}. Using sample rate @var{frequency}
-bits per sample @var{bits} and number of channels @var{channels}.
-
-Defaults:
- at itemize @minus
- at item Sample rate = 44100 Hz - CD quality
- at item Bits = 16
- at item Number of channels = 2 - Stereo
- at end itemize
-ETEXI
-
-#ifdef HAS_AUDIO
- {
- .name = "stopcapture",
- .args_type = "n:i",
- .params = "capture index",
- .help = "stop capture",
- .mhandler.cmd = do_stop_capture,
- },
-#endif
-STEXI
- at item stopcapture @var{index}
- at findex stopcapture
-Stop capture with a given @var{index}, index can be obtained with
- at example
-info capture
- at end example
-ETEXI
-
- {
- .name = "memsave",
- .args_type = "val:l,size:i,filename:s",
- .params = "addr size file",
- .help = "save to disk virtual memory dump starting at 'addr' of size 'size'",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_memory_save,
- },
-
-STEXI
- at item memsave @var{addr} @var{size} @var{file}
- at findex memsave
-save to disk virtual memory dump starting at @var{addr} of size @var{size}.
-ETEXI
-
- {
- .name = "pmemsave",
- .args_type = "val:l,size:i,filename:s",
- .params = "addr size file",
- .help = "save to disk physical memory dump starting at 'addr' of size 'size'",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_physical_memory_save,
- },
-
-STEXI
- at item pmemsave @var{addr} @var{size} @var{file}
- at findex pmemsave
-save to disk physical memory dump starting at @var{addr} of size @var{size}.
-ETEXI
-
- {
- .name = "boot_set",
- .args_type = "bootdevice:s",
- .params = "bootdevice",
- .help = "define new values for the boot device list",
- .mhandler.cmd = do_boot_set,
- },
-
-STEXI
- at item boot_set @var{bootdevicelist}
- at findex boot_set
-
-Define new values for the boot device list. Those values will override
-the values specified on the command line through the @code{-boot} option.
-
-The values that can be specified here depend on the machine type, but are
-the same that can be specified in the @code{-boot} command line option.
-ETEXI
-
-#if defined(TARGET_I386)
- {
- .name = "nmi",
- .args_type = "cpu_index:i",
- .params = "cpu",
- .help = "inject an NMI on the given CPU",
- .mhandler.cmd = do_inject_nmi,
- },
-#endif
-STEXI
- at item nmi @var{cpu}
- at findex nmi
-Inject an NMI on the given CPU (x86 only).
-ETEXI
-
- {
- .name = "migrate",
- .args_type = "detach:-d,blk:-b,inc:-i,uri:s",
- .params = "[-d] [-b] [-i] uri",
- .help = "migrate to URI (using -d to not wait for completion)"
- "\n\t\t\t -b for migration without shared storage with"
- " full copy of disk\n\t\t\t -i for migration without "
- "shared storage with incremental copy of disk "
- "(base image shared between src and destination)",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_migrate,
- },
-
-
-STEXI
- at item migrate [-d] [-b] [-i] @var{uri}
- at findex migrate
-Migrate to @var{uri} (using -d to not wait for completion).
- -b for migration with full copy of disk
- -i for migration with incremental copy of disk (base image is shared)
-ETEXI
-
- {
- .name = "migrate_cancel",
- .args_type = "",
- .params = "",
- .help = "cancel the current VM migration",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_migrate_cancel,
- },
-
-STEXI
- at item migrate_cancel
- at findex migrate_cancel
-Cancel the current VM migration.
-ETEXI
-
- {
- .name = "migrate_set_speed",
- .args_type = "value:f",
- .params = "value",
- .help = "set maximum speed (in bytes) for migrations",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_migrate_set_speed,
- },
-
-STEXI
- at item migrate_set_speed @var{value}
- at findex migrate_set_speed
-Set maximum speed to @var{value} (in bytes) for migrations.
-ETEXI
-
- {
- .name = "migrate_set_downtime",
- .args_type = "value:T",
- .params = "value",
- .help = "set maximum tolerated downtime (in seconds) for migrations",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_migrate_set_downtime,
- },
-
-STEXI
- at item migrate_set_downtime @var{second}
- at findex migrate_set_downtime
-Set maximum tolerated downtime (in seconds) for migration.
-ETEXI
-
-#if defined(TARGET_I386)
- {
- .name = "drive_add",
- .args_type = "pci_addr:s,opts:s",
- .params = "[[<domain>:]<bus>:]<slot>\n"
- "[file=file][,if=type][,bus=n]\n"
- "[,unit=m][,media=d][index=i]\n"
- "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
- "[snapshot=on|off][,cache=on|off]",
- .help = "add drive to PCI storage controller",
- .mhandler.cmd = drive_hot_add,
- },
-#endif
-
-STEXI
- at item drive_add
- at findex drive_add
-Add drive to PCI storage controller.
-ETEXI
-
-#if defined(TARGET_I386)
- {
- .name = "pci_add",
- .args_type = "pci_addr:s,type:s,opts:s?",
- .params = "auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...",
- .help = "hot-add PCI device",
- .mhandler.cmd = pci_device_hot_add,
- },
-#endif
-
-STEXI
- at item pci_add
- at findex pci_add
-Hot-add PCI device.
-ETEXI
-
-#if defined(TARGET_I386)
- {
- .name = "pci_del",
- .args_type = "pci_addr:s",
- .params = "[[<domain>:]<bus>:]<slot>",
- .help = "hot remove PCI device",
- .mhandler.cmd = do_pci_device_hot_remove,
- },
-#endif
-
-STEXI
- at item pci_del
- at findex pci_del
-Hot remove PCI device.
-ETEXI
-
- {
- .name = "host_net_add",
- .args_type = "device:s,opts:s?",
- .params = "tap|user|socket|vde|dump [options]",
- .help = "add host VLAN client",
- .mhandler.cmd = net_host_device_add,
- },
-
-STEXI
- at item host_net_add
- at findex host_net_add
-Add host VLAN client.
-ETEXI
-
- {
- .name = "host_net_remove",
- .args_type = "vlan_id:i,device:s",
- .params = "vlan_id name",
- .help = "remove host VLAN client",
- .mhandler.cmd = net_host_device_remove,
- },
-
-STEXI
- at item host_net_remove
- at findex host_net_remove
-Remove host VLAN client.
-ETEXI
-
- {
- .name = "netdev_add",
- .args_type = "netdev:O",
- .params = "[user|tap|socket],id=str[,prop=value][,...]",
- .help = "add host network device",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_netdev_add,
- },
-
-STEXI
- at item netdev_add
- at findex netdev_add
-Add host network device.
-ETEXI
-
- {
- .name = "netdev_del",
- .args_type = "id:s",
- .params = "id",
- .help = "remove host network device",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_netdev_del,
- },
-
-STEXI
- at item netdev_del
- at findex netdev_del
-Remove host network device.
-ETEXI
-
-#ifdef CONFIG_SLIRP
- {
- .name = "hostfwd_add",
- .args_type = "arg1:s,arg2:s?,arg3:s?",
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
- .help = "redirect TCP or UDP connections from host to guest (requires -net user)",
- .mhandler.cmd = net_slirp_hostfwd_add,
- },
-#endif
-STEXI
- at item hostfwd_add
- at findex hostfwd_add
-Redirect TCP or UDP connections from host to guest (requires -net user).
-ETEXI
-
-#ifdef CONFIG_SLIRP
- {
- .name = "hostfwd_remove",
- .args_type = "arg1:s,arg2:s?,arg3:s?",
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
- .help = "remove host-to-guest TCP or UDP redirection",
- .mhandler.cmd = net_slirp_hostfwd_remove,
- },
-
-#endif
-STEXI
- at item hostfwd_remove
- at findex hostfwd_remove
-Remove host-to-guest TCP or UDP redirection.
-ETEXI
-
- {
- .name = "balloon",
- .args_type = "value:M",
- .params = "target",
- .help = "request VM to change its memory allocation (in MB)",
- .user_print = monitor_user_noop,
- .mhandler.cmd_async = do_balloon,
- .flags = MONITOR_CMD_ASYNC,
- },
-
-STEXI
- at item balloon @var{value}
- at findex balloon
-Request VM to change its memory allocation to @var{value} (in MB).
-ETEXI
-
- {
- .name = "set_link",
- .args_type = "name:s,up:b",
- .params = "name on|off",
- .help = "change the link status of a network adapter",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_set_link,
- },
-
-STEXI
- at item set_link @var{name} [on|off]
- at findex set_link
-Switch link @var{name} on (i.e. up) or off (i.e. down).
-ETEXI
-
- {
- .name = "watchdog_action",
- .args_type = "action:s",
- .params = "[reset|shutdown|poweroff|pause|debug|none]",
- .help = "change watchdog action",
- .mhandler.cmd = do_watchdog_action,
- },
-
-STEXI
- at item watchdog_action
- at findex watchdog_action
-Change watchdog action.
-ETEXI
-
- {
- .name = "acl_show",
- .args_type = "aclname:s",
- .params = "aclname",
- .help = "list rules in the access control list",
- .mhandler.cmd = do_acl_show,
- },
-
-STEXI
- at item acl_show @var{aclname}
- at findex acl_show
-List all the matching rules in the access control list, and the default
-policy. There are currently two named access control lists,
- at var{vnc.x509dname} and @var{vnc.username} matching on the x509 client
-certificate distinguished name, and SASL username respectively.
-ETEXI
-
- {
- .name = "acl_policy",
- .args_type = "aclname:s,policy:s",
- .params = "aclname allow|deny",
- .help = "set default access control list policy",
- .mhandler.cmd = do_acl_policy,
- },
-
-STEXI
- at item acl_policy @var{aclname} @code{allow|deny}
- at findex acl_policy
-Set the default access control list policy, used in the event that
-none of the explicit rules match. The default policy at startup is
-always @code{deny}.
-ETEXI
-
- {
- .name = "acl_add",
- .args_type = "aclname:s,match:s,policy:s,index:i?",
- .params = "aclname match allow|deny [index]",
- .help = "add a match rule to the access control list",
- .mhandler.cmd = do_acl_add,
- },
-
-STEXI
- at item acl_add @var{aclname} @var{match} @code{allow|deny} [@var{index}]
- at findex acl_add
-Add a match rule to the access control list, allowing or denying access.
-The match will normally be an exact username or x509 distinguished name,
-but can optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to
-allow all users in the @code{EXAMPLE.COM} kerberos realm. The match will
-normally be appended to the end of the ACL, but can be inserted
-earlier in the list if the optional @var{index} parameter is supplied.
-ETEXI
-
- {
- .name = "acl_remove",
- .args_type = "aclname:s,match:s",
- .params = "aclname match",
- .help = "remove a match rule from the access control list",
- .mhandler.cmd = do_acl_remove,
- },
-
-STEXI
- at item acl_remove @var{aclname} @var{match}
- at findex acl_remove
-Remove the specified match rule from the access control list.
-ETEXI
-
- {
- .name = "acl_reset",
- .args_type = "aclname:s",
- .params = "aclname",
- .help = "reset the access control list",
- .mhandler.cmd = do_acl_reset,
- },
-
-STEXI
- at item acl_reset @var{aclname}
- at findex acl_reset
-Remove all matches from the access control list, and set the default
-policy back to @code{deny}.
-ETEXI
-
-#if defined(TARGET_I386)
-
- {
- .name = "mce",
- .args_type = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
- .params = "cpu bank status mcgstatus addr misc",
- .help = "inject a MCE on the given CPU",
- .mhandler.cmd = do_inject_mce,
- },
-
-#endif
-STEXI
- at item mce @var{cpu} @var{bank} @var{status} @var{mcgstatus} @var{addr} @var{misc}
- at findex mce (x86)
-Inject an MCE on the given CPU (x86 only).
-ETEXI
-
- {
- .name = "getfd",
- .args_type = "fdname:s",
- .params = "getfd name",
- .help = "receive a file descriptor via SCM rights and assign it a name",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_getfd,
- },
-
-STEXI
- at item getfd @var{fdname}
- at findex getfd
-If a file descriptor is passed alongside this command using the SCM_RIGHTS
-mechanism on unix sockets, it is stored using the name @var{fdname} for
-later use by other monitor commands.
-ETEXI
-
- {
- .name = "closefd",
- .args_type = "fdname:s",
- .params = "closefd name",
- .help = "close a file descriptor previously passed via SCM rights",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_closefd,
- },
-
-STEXI
- at item closefd @var{fdname}
- at findex closefd
-Close the file descriptor previously assigned to @var{fdname} using the
- at code{getfd} command. This is only needed if the file descriptor was never
-used by another monitor command.
-ETEXI
-
- {
- .name = "block_passwd",
- .args_type = "device:B,password:s",
- .params = "block_passwd device password",
- .help = "set the password of encrypted block devices",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_block_set_passwd,
- },
-
-STEXI
- at item block_passwd @var{device} @var{password}
- at findex block_passwd
-Set the encrypted device @var{device} password to @var{password}
-ETEXI
-
- {
- .name = "info",
- .args_type = "item:s?",
- .params = "[subcommand]",
- .help = "show various information about the system state",
- .mhandler.cmd = do_info,
- },
-
-STEXI
- at item info @var{subcommand}
- at findex info
-Show various information about the system state.
-
- at table @option
- at item info version
-show the version of QEMU
- at item info network
-show the various VLANs and the associated devices
- at item info chardev
-show the character devices
- at item info block
-show the block devices
- at item info blockstats
-show block device statistics
- at item info registers
-show the cpu registers
- at item info cpus
-show infos for each CPU
- at item info history
-show the command line history
- at item info irq
-show the interrupts statistics (if available)
- at item info pic
-show i8259 (PIC) state
- at item info pci
-show emulated PCI device info
- at item info tlb
-show virtual to physical memory mappings (i386 only)
- at item info mem
-show the active virtual memory mappings (i386 only)
- at item info jit
-show dynamic compiler info
- at item info kvm
-show KVM information
- at item info numa
-show NUMA information
- at item info kvm
-show KVM information
- at item info usb
-show USB devices plugged on the virtual USB hub
- at item info usbhost
-show all USB host devices
- at item info profile
-show profiling information
- at item info capture
-show information about active capturing
- at item info snapshots
-show list of VM snapshots
- at item info status
-show the current VM status (running|paused)
- at item info pcmcia
-show guest PCMCIA status
- at item info mice
-show which guest mouse is receiving events
- at item info vnc
-show the vnc server status
- at item info name
-show the current VM name
- at item info uuid
-show the current VM UUID
- at item info cpustats
-show CPU statistics
- at item info usernet
-show user network stack connection states
- at item info migrate
-show migration status
- at item info balloon
-show balloon information
- at item info qtree
-show device tree
- at item info qdm
-show qdev device model list
- at item info roms
-show roms
- at end table
-ETEXI
-
-#ifdef CONFIG_SIMPLE_TRACE
-STEXI
- at item info trace
-show contents of trace buffer
- at item info trace-events
-show available trace events and their state
-ETEXI
-#endif
-
-STEXI
- at end table
-ETEXI
commit fc29df759e7499446220349809a920ed2dfbc466
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Thu Sep 16 11:11:18 2010 -0300
QMP: Introduce qmp_call_cmd()
Calls a QObject handler and emits the QMP response, also drops
monitor_call_handler() which is now unused.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 03f3c18..3f3c9bf 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3880,29 +3880,6 @@ static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
}
}
-static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd,
- const QDict *params)
-{
- int ret;
- QObject *data = NULL;
-
- mon_print_count_init(mon);
-
- ret = cmd->mhandler.cmd_new(mon, params, &data);
- handler_audit(mon, cmd, ret);
-
- if (monitor_ctrl_mode(mon)) {
- /* Monitor Protocol */
- monitor_protocol_emitter(mon, data);
- } else {
- /* User Protocol */
- if (data)
- cmd->user_print(mon, data);
- }
-
- qobject_decref(data);
-}
-
static void handle_user_command(Monitor *mon, const char *cmdline)
{
QDict *qdict;
@@ -4433,6 +4410,20 @@ static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd)
}
}
+static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd,
+ const QDict *params)
+{
+ int ret;
+ QObject *data = NULL;
+
+ mon_print_count_init(mon);
+
+ ret = cmd->mhandler.cmd_new(mon, params, &data);
+ handler_audit(mon, cmd, ret);
+ monitor_protocol_emitter(mon, data);
+ qobject_decref(data);
+}
+
static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
{
int err;
@@ -4500,7 +4491,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
} else {
- monitor_call_handler(mon, cmd, args);
+ qmp_call_cmd(mon, cmd, args);
}
goto out;
commit de79ba6f53fa78a6132a67c7ff134014dc8479e7
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Thu Sep 16 11:06:11 2010 -0300
Monitor: Directly call QObject handlers
This avoids handle_user_command() calling monitor_call_handler(),
which is currently shared with QMP.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 7959504..03f3c18 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3917,7 +3917,15 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
if (handler_is_async(cmd)) {
user_async_cmd_handler(mon, cmd, qdict);
} else if (handler_is_qobject(cmd)) {
- monitor_call_handler(mon, cmd, qdict);
+ QObject *data = NULL;
+
+ /* XXX: ignores the error code */
+ cmd->mhandler.cmd_new(mon, qdict, &data);
+ assert(!monitor_has_error(mon));
+ if (data) {
+ cmd->user_print(mon, data);
+ qobject_decref(data);
+ }
} else {
cmd->mhandler.cmd(mon, qdict);
}
commit 4903de0cebb6306e8c660dc0ce3e66fe3b5c35f9
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Thu Sep 16 11:01:32 2010 -0300
Monitor: Rename monitor_handler_is_async()
Let's follow the convention introduced by the previous commit and
call it handler_is_async().
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index b9dab78..7959504 100644
--- a/monitor.c
+++ b/monitor.c
@@ -335,7 +335,7 @@ static inline int handler_is_qobject(const mon_cmd_t *cmd)
return cmd->user_print != NULL;
}
-static inline bool monitor_handler_is_async(const mon_cmd_t *cmd)
+static inline bool handler_is_async(const mon_cmd_t *cmd)
{
return cmd->flags & MONITOR_CMD_ASYNC;
}
@@ -652,7 +652,7 @@ static void do_info(Monitor *mon, const QDict *qdict)
goto help;
}
- if (monitor_handler_is_async(cmd)) {
+ if (handler_is_async(cmd)) {
user_async_info_handler(mon, cmd);
} else if (handler_is_qobject(cmd)) {
QObject *info_data = NULL;
@@ -3914,7 +3914,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
if (!cmd)
goto out;
- if (monitor_handler_is_async(cmd)) {
+ if (handler_is_async(cmd)) {
user_async_cmd_handler(mon, cmd, qdict);
} else if (handler_is_qobject(cmd)) {
monitor_call_handler(mon, cmd, qdict);
@@ -4411,7 +4411,7 @@ static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd)
{
QObject *ret_data = NULL;
- if (monitor_handler_is_async(cmd)) {
+ if (handler_is_async(cmd)) {
qmp_async_info_handler(mon, cmd);
if (monitor_has_error(mon)) {
monitor_protocol_emitter(mon, NULL);
@@ -4485,7 +4485,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
if (query_cmd) {
qmp_call_query_cmd(mon, cmd);
- } else if (monitor_handler_is_async(cmd)) {
+ } else if (handler_is_async(cmd)) {
err = qmp_async_cmd_handler(mon, cmd, args);
if (err) {
/* emit the error response */
commit 9e80721effc4457c1fca38d3b3e9de6a32d5bcd7
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Thu Sep 16 10:58:59 2010 -0300
Monitor: Rename monitor_handler_ported()
That name makes no sense anymore, as dispatch tables have been split,
a better name is handler_is_qobject(), which really communicates
the handler's type.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 8f90250..b9dab78 100644
--- a/monitor.c
+++ b/monitor.c
@@ -330,7 +330,7 @@ static int monitor_fprintf(FILE *stream, const char *fmt, ...)
static void monitor_user_noop(Monitor *mon, const QObject *data) { }
-static inline int monitor_handler_ported(const mon_cmd_t *cmd)
+static inline int handler_is_qobject(const mon_cmd_t *cmd)
{
return cmd->user_print != NULL;
}
@@ -654,7 +654,7 @@ static void do_info(Monitor *mon, const QDict *qdict)
if (monitor_handler_is_async(cmd)) {
user_async_info_handler(mon, cmd);
- } else if (monitor_handler_ported(cmd)) {
+ } else if (handler_is_qobject(cmd)) {
QObject *info_data = NULL;
cmd->mhandler.info_new(mon, &info_data);
@@ -3916,7 +3916,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
if (monitor_handler_is_async(cmd)) {
user_async_cmd_handler(mon, cmd, qdict);
- } else if (monitor_handler_ported(cmd)) {
+ } else if (handler_is_qobject(cmd)) {
monitor_call_handler(mon, cmd, qdict);
} else {
cmd->mhandler.cmd(mon, qdict);
commit 0e19a62770a7a0876869432c69a5a5f2d7646e12
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Thu Sep 16 10:47:54 2010 -0300
Monitor: Drop monitor_cmd_user_only()
This function was only needed when QMP and HMP were sharing dispatch
tables, this is no longer true so just drop it.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index b43277e..8f90250 100644
--- a/monitor.c
+++ b/monitor.c
@@ -340,11 +340,6 @@ static inline bool monitor_handler_is_async(const mon_cmd_t *cmd)
return cmd->flags & MONITOR_CMD_ASYNC;
}
-static inline bool monitor_cmd_user_only(const mon_cmd_t *cmd)
-{
- return (cmd->flags & MONITOR_CMD_USER_ONLY);
-}
-
static inline int monitor_has_error(const Monitor *mon)
{
return mon->error != NULL;
diff --git a/monitor.h b/monitor.h
index f2122b5..44c3625 100644
--- a/monitor.h
+++ b/monitor.h
@@ -18,7 +18,6 @@ extern Monitor *default_mon;
/* flags for monitor commands */
#define MONITOR_CMD_ASYNC 0x0001
-#define MONITOR_CMD_USER_ONLY 0x0002
/* QMP events */
typedef enum MonitorEvent {
commit 30f5041ef1ba534af9308d840bf359a50597ba5d
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Mon Sep 13 15:34:56 2010 -0300
Monitor: Drop QMP info from the qemu-monitor.hx file
QMP has its own dispatch table and documentation file
(qmp-commands.hx), we can now drop the following QMP specific info
from qemu-monitor.hx:
o SQMP/EQMP sections
o The qmp_capabilities command
o The query-commands command
However, note that QObject handlers entries are not being removed.
This will only happen when we introduce a proper QMP call interface.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 6e62643..b43277e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2352,14 +2352,6 @@ static const mon_cmd_t info_cmds[] = {
.mhandler.info_new = do_info_version,
},
{
- .name = "commands",
- .args_type = "",
- .params = "",
- .help = "list QMP available commands",
- .user_print = monitor_user_noop,
- .mhandler.info_new = do_info_commands,
- },
- {
.name = "network",
.args_type = "",
.params = "",
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 57d28ac..81999aa 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -1,70 +1,10 @@
HXCOMM Use DEFHEADING() to define headings in both help text and texi
HXCOMM Text between STEXI and ETEXI are copied to texi version and
HXCOMM discarded from C version
-HXCOMM Text between SQMP and EQMP is copied to the QMP documention file and
-HXCOMM does not show up in the other formats.
HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
HXCOMM monitor commands
HXCOMM HXCOMM can be used for comments, discarded from both texi and C
-SQMP
- QMP Supported Commands
- ----------------------
-
-This document describes all commands currently supported by QMP.
-
-Most of the time their usage is exactly the same as in the user Monitor, this
-means that any other document which also describe commands (the manpage,
-QEMU's manual, etc) can and should be consulted.
-
-QMP has two types of commands: regular and query commands. Regular commands
-usually change the Virtual Machine's state someway, while query commands just
-return information. The sections below are divided accordingly.
-
-It's important to observe that all communication examples are formatted in
-a reader-friendly way, so that they're easier to understand. However, in real
-protocol usage, they're emitted as a single line.
-
-Also, the following notation is used to denote data flow:
-
--> data issued by the Client
-<- Server data response
-
-Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed
-information on the Server command and response formats.
-
-NOTE: This document is temporary and will be replaced soon.
-
-1. Stability Considerations
-===========================
-
-The current QMP command set (described in this file) may be useful for a
-number of use cases, however it's limited and several commands have bad
-defined semantics, specially with regard to command completion.
-
-These problems are going to be solved incrementally in the next QEMU releases
-and we're going to establish a deprecation policy for badly defined commands.
-
-If you're planning to adopt QMP, please observe the following:
-
- 1. The deprecation policy will take efect and be documented soon, please
- check the documentation of each used command as soon as a new release of
- QEMU is available
-
- 2. DO NOT rely on anything which is not explicit documented
-
- 3. Errors, in special, are not documented. Applications should NOT check
- for specific errors classes or data (it's strongly recommended to only
- check for the "error" key)
-
-2. Regular Commands
-===================
-
-Server's responses in the examples below are always a success response, please
-refer to the QMP specification for more details on error responses.
-
-EQMP
-
STEXI
@table @option
ETEXI
@@ -111,20 +51,6 @@ STEXI
@findex quit
Quit the emulator.
ETEXI
-SQMP
-quit
-----
-
-Quit the emulator.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "quit" }
-<- { "return": {} }
-
-EQMP
{
.name = "eject",
@@ -140,25 +66,6 @@ STEXI
@findex eject
Eject a removable medium (use -f to force it).
ETEXI
-SQMP
-eject
------
-
-Eject a removable medium.
-
-Arguments:
-
-- force: force ejection (json-bool, optional)
-- device: device name (json-string)
-
-Example:
-
--> { "execute": "eject", "arguments": { "device": "ide1-cd0" } }
-<- { "return": {} }
-
-Note: The "force" argument defaults to false.
-
-EQMP
{
.name = "change",
@@ -206,35 +113,6 @@ Password: ********
@end table
ETEXI
-SQMP
-change
-------
-
-Change a removable medium or VNC configuration.
-
-Arguments:
-
-- "device": device name (json-string)
-- "target": filename or item (json-string)
-- "arg": additional argument (json-string, optional)
-
-Examples:
-
-1. Change a removable medium
-
--> { "execute": "change",
- "arguments": { "device": "ide1-cd0",
- "target": "/srv/images/Fedora-12-x86_64-DVD.iso" } }
-<- { "return": {} }
-
-2. Change VNC password
-
--> { "execute": "change",
- "arguments": { "device": "vnc", "target": "password",
- "arg": "foobar1" } }
-<- { "return": {} }
-
-EQMP
{
.name = "screendump",
@@ -250,22 +128,6 @@ STEXI
@findex screendump
Save screen into PPM image @var{filename}.
ETEXI
-SQMP
-screendump
-----------
-
-Save screen into PPM image.
-
-Arguments:
-
-- "filename": file path (json-string)
-
-Example:
-
--> { "execute": "screendump", "arguments": { "filename": "/tmp/image" } }
-<- { "return": {} }
-
-EQMP
{
.name = "logfile",
@@ -400,20 +262,6 @@ STEXI
@findex stop
Stop emulation.
ETEXI
-SQMP
-stop
-----
-
-Stop the emulator.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "stop" }
-<- { "return": {} }
-
-EQMP
{
.name = "c|cont",
@@ -429,20 +277,6 @@ STEXI
@findex cont
Resume emulation.
ETEXI
-SQMP
-cont
-----
-
-Resume emulation.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "cont" }
-<- { "return": {} }
-
-EQMP
{
.name = "gdbserver",
@@ -617,20 +451,6 @@ STEXI
Reset the system.
ETEXI
-SQMP
-system_reset
-------------
-
-Reset the system.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "system_reset" }
-<- { "return": {} }
-
-EQMP
{
.name = "system_powerdown",
@@ -647,20 +467,6 @@ STEXI
Power down the system (if supported).
ETEXI
-SQMP
-system_powerdown
-----------------
-
-Send system power down event.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "system_powerdown" }
-<- { "return": {} }
-
-EQMP
{
.name = "sum",
@@ -725,33 +531,6 @@ STEXI
Add device.
ETEXI
-SQMP
-device_add
-----------
-
-Add a device.
-
-Arguments:
-
-- "driver": the name of the new device's driver (json-string)
-- "bus": the device's parent bus (device tree path, json-string, optional)
-- "id": the device's ID, must be unique (json-string)
-- device properties
-
-Example:
-
--> { "execute": "device_add", "arguments": { "driver": "e1000", "id": "net1" } }
-<- { "return": {} }
-
-Notes:
-
-(1) For detailed information about this command, please refer to the
- 'docs/qdev-device-use.txt' file.
-
-(2) It's possible to list device properties by running QEMU with the
- "-device DEVICE,\?" command-line argument, where DEVICE is the device's name
-
-EQMP
{
.name = "device_del",
@@ -768,22 +547,6 @@ STEXI
Remove device @var{id}.
ETEXI
-SQMP
-device_del
-----------
-
-Remove a device.
-
-Arguments:
-
-- "id": the device's ID (json-string)
-
-Example:
-
--> { "execute": "device_del", "arguments": { "id": "net1" } }
-<- { "return": {} }
-
-EQMP
{
.name = "cpu",
@@ -799,24 +562,6 @@ STEXI
@findex cpu
Set the default CPU.
ETEXI
-SQMP
-cpu
----
-
-Set the default CPU.
-
-Arguments:
-
-- "index": the CPU's index (json-int)
-
-Example:
-
--> { "execute": "cpu", "arguments": { "index": 0 } }
-<- { "return": {} }
-
-Note: CPUs' indexes are obtained with the 'query-cpus' command.
-
-EQMP
{
.name = "mouse_move",
@@ -920,29 +665,6 @@ STEXI
@findex memsave
save to disk virtual memory dump starting at @var{addr} of size @var{size}.
ETEXI
-SQMP
-memsave
--------
-
-Save to disk virtual memory dump starting at 'val' of size 'size'.
-
-Arguments:
-
-- "val": the starting address (json-int)
-- "size": the memory size, in bytes (json-int)
-- "filename": file path (json-string)
-
-Example:
-
--> { "execute": "memsave",
- "arguments": { "val": 10,
- "size": 100,
- "filename": "/tmp/virtual-mem-dump" } }
-<- { "return": {} }
-
-Note: Depends on the current CPU.
-
-EQMP
{
.name = "pmemsave",
@@ -958,27 +680,6 @@ STEXI
@findex pmemsave
save to disk physical memory dump starting at @var{addr} of size @var{size}.
ETEXI
-SQMP
-pmemsave
---------
-
-Save to disk physical memory dump starting at 'val' of size 'size'.
-
-Arguments:
-
-- "val": the starting address (json-int)
-- "size": the memory size, in bytes (json-int)
-- "filename": file path (json-string)
-
-Example:
-
--> { "execute": "pmemsave",
- "arguments": { "val": 10,
- "size": 100,
- "filename": "/tmp/physical-mem-dump" } }
-<- { "return": {} }
-
-EQMP
{
.name = "boot_set",
@@ -1035,32 +736,6 @@ Migrate to @var{uri} (using -d to not wait for completion).
-b for migration with full copy of disk
-i for migration with incremental copy of disk (base image is shared)
ETEXI
-SQMP
-migrate
--------
-
-Migrate to URI.
-
-Arguments:
-
-- "blk": block migration, full disk copy (json-bool, optional)
-- "inc": incremental disk copy (json-bool, optional)
-- "uri": Destination URI (json-string)
-
-Example:
-
--> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } }
-<- { "return": {} }
-
-Notes:
-
-(1) The 'query-migrate' command should be used to check migration's progress
- and final result (this information is provided by the 'status' member)
-(2) All boolean arguments default to false
-(3) The user Monitor's "detach" argument is invalid in QMP and should not
- be used
-
-EQMP
{
.name = "migrate_cancel",
@@ -1076,20 +751,6 @@ STEXI
@findex migrate_cancel
Cancel the current VM migration.
ETEXI
-SQMP
-migrate_cancel
---------------
-
-Cancel the current migration.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "migrate_cancel" }
-<- { "return": {} }
-
-EQMP
{
.name = "migrate_set_speed",
@@ -1105,22 +766,6 @@ STEXI
@findex migrate_set_speed
Set maximum speed to @var{value} (in bytes) for migrations.
ETEXI
-SQMP
-migrate_set_speed
------------------
-
-Set maximum speed for migrations.
-
-Arguments:
-
-- "value": maximum speed, in bytes per second (json-number)
-
-Example:
-
--> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } }
-<- { "return": {} }
-
-EQMP
{
.name = "migrate_set_downtime",
@@ -1136,22 +781,6 @@ STEXI
@findex migrate_set_downtime
Set maximum tolerated downtime (in seconds) for migration.
ETEXI
-SQMP
-migrate_set_downtime
---------------------
-
-Set maximum tolerated downtime (in seconds) for migrations.
-
-Arguments:
-
-- "value": maximum downtime (json-number)
-
-Example:
-
--> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } }
-<- { "return": {} }
-
-EQMP
#if defined(TARGET_I386)
{
@@ -1247,28 +876,6 @@ STEXI
@findex netdev_add
Add host network device.
ETEXI
-SQMP
-netdev_add
-----------
-
-Add host network device.
-
-Arguments:
-
-- "type": the device type, "tap", "user", ... (json-string)
-- "id": the device's ID, must be unique (json-string)
-- device options
-
-Example:
-
--> { "execute": "netdev_add", "arguments": { "type": "user", "id": "netdev1" } }
-<- { "return": {} }
-
-Note: The supported device options are the same ones supported by the '-net'
- command-line argument, which are listed in the '-help' output or QEMU's
- manual
-
-EQMP
{
.name = "netdev_del",
@@ -1284,22 +891,6 @@ STEXI
@findex netdev_del
Remove host network device.
ETEXI
-SQMP
-netdev_del
-----------
-
-Remove host network device.
-
-Arguments:
-
-- "id": the device's ID, must be unique (json-string)
-
-Example:
-
--> { "execute": "netdev_del", "arguments": { "id": "netdev1" } }
-<- { "return": {} }
-
-EQMP
#ifdef CONFIG_SLIRP
{
@@ -1347,22 +938,6 @@ STEXI
@findex balloon
Request VM to change its memory allocation to @var{value} (in MB).
ETEXI
-SQMP
-balloon
--------
-
-Request VM to change its memory allocation (in bytes).
-
-Arguments:
-
-- "value": New memory allocation (json-int)
-
-Example:
-
--> { "execute": "balloon", "arguments": { "value": 536870912 } }
-<- { "return": {} }
-
-EQMP
{
.name = "set_link",
@@ -1378,23 +953,6 @@ STEXI
@findex set_link
Switch link @var{name} on (i.e. up) or off (i.e. down).
ETEXI
-SQMP
-set_link
---------
-
-Change the link status of a network adapter.
-
-Arguments:
-
-- "name": network device name (json-string)
-- "up": status is up (json-bool)
-
-Example:
-
--> { "execute": "set_link", "arguments": { "name": "e1000.0", "up": false } }
-<- { "return": {} }
-
-EQMP
{
.name = "watchdog_action",
@@ -1524,22 +1082,6 @@ If a file descriptor is passed alongside this command using the SCM_RIGHTS
mechanism on unix sockets, it is stored using the name @var{fdname} for
later use by other monitor commands.
ETEXI
-SQMP
-getfd
------
-
-Receive a file descriptor via SCM rights and assign it a name.
-
-Arguments:
-
-- "fdname": file descriptor name (json-string)
-
-Example:
-
--> { "execute": "getfd", "arguments": { "fdname": "fd1" } }
-<- { "return": {} }
-
-EQMP
{
.name = "closefd",
@@ -1557,22 +1099,6 @@ Close the file descriptor previously assigned to @var{fdname} using the
@code{getfd} command. This is only needed if the file descriptor was never
used by another monitor command.
ETEXI
-SQMP
-closefd
--------
-
-Close a file descriptor previously passed via SCM rights.
-
-Arguments:
-
-- "fdname": file descriptor name (json-string)
-
-Example:
-
--> { "execute": "closefd", "arguments": { "fdname": "fd1" } }
-<- { "return": {} }
-
-EQMP
{
.name = "block_passwd",
@@ -1588,66 +1114,6 @@ STEXI
@findex block_passwd
Set the encrypted device @var{device} password to @var{password}
ETEXI
-SQMP
-block_passwd
-------------
-
-Set the password of encrypted block devices.
-
-Arguments:
-
-- "device": device name (json-string)
-- "password": password (json-string)
-
-Example:
-
--> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0",
- "password": "12345" } }
-<- { "return": {} }
-
-EQMP
-
- {
- .name = "qmp_capabilities",
- .args_type = "",
- .params = "",
- .help = "enable QMP capabilities",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_qmp_capabilities,
- },
-
-STEXI
- at item qmp_capabilities
- at findex qmp_capabilities
-Enable the specified QMP capabilities
-ETEXI
-SQMP
-qmp_capabilities
-----------------
-
-Enable QMP capabilities.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "qmp_capabilities" }
-<- { "return": {} }
-
-Note: This command must be issued before issuing any other command.
-
-EQMP
-
-
-HXCOMM Keep the 'info' command at the end!
-HXCOMM This is required for the QMP documentation layout.
-
-SQMP
-
-3. Query Commands
-=================
-
-EQMP
{
.name = "info",
@@ -1665,579 +1131,38 @@ Show various information about the system state.
@table @option
@item info version
show the version of QEMU
-ETEXI
-SQMP
-query-version
--------------
-
-Show QEMU version.
-
-Return a json-object with the following information:
-
-- "qemu": A json-object containing three integer values:
- - "major": QEMU's major version (json-int)
- - "minor": QEMU's minor version (json-int)
- - "micro": QEMU's micro version (json-int)
-- "package": package's version (json-string)
-
-Example:
-
--> { "execute": "query-version" }
-<- {
- "return":{
- "qemu":{
- "major":0,
- "minor":11,
- "micro":5
- },
- "package":""
- }
- }
-
-EQMP
-
-STEXI
- at item info commands
-list QMP available commands
-ETEXI
-SQMP
-query-commands
---------------
-
-List QMP available commands.
-
-Each command is represented by a json-object, the returned value is a json-array
-of all commands.
-
-Each json-object contain:
-
-- "name": command's name (json-string)
-
-Example:
-
--> { "execute": "query-commands" }
-<- {
- "return":[
- {
- "name":"query-balloon"
- },
- {
- "name":"system_powerdown"
- }
- ]
- }
-
-Note: This example has been shortened as the real response is too long.
-
-EQMP
-
-STEXI
@item info network
show the various VLANs and the associated devices
-ETEXI
-
-STEXI
@item info chardev
show the character devices
-ETEXI
-SQMP
-query-chardev
--------------
-
-Each device is represented by a json-object. The returned value is a json-array
-of all devices.
-
-Each json-object contain the following:
-
-- "label": device's label (json-string)
-- "filename": device's file (json-string)
-
-Example:
-
--> { "execute": "query-chardev" }
-<- {
- "return":[
- {
- "label":"monitor",
- "filename":"stdio"
- },
- {
- "label":"serial0",
- "filename":"vc"
- }
- ]
- }
-
-EQMP
-
-STEXI
@item info block
show the block devices
-ETEXI
-SQMP
-query-block
------------
-
-Show the block devices.
-
-Each block device information is stored in a json-object and the returned value
-is a json-array of all devices.
-
-Each json-object contain the following:
-
-- "device": device name (json-string)
-- "type": device type (json-string)
- - Possible values: "hd", "cdrom", "floppy", "unknown"
-- "removable": true if the device is removable, false otherwise (json-bool)
-- "locked": true if the device is locked, false otherwise (json-bool)
-- "inserted": only present if the device is inserted, it is a json-object
- containing the following:
- - "file": device file name (json-string)
- - "ro": true if read-only, false otherwise (json-bool)
- - "drv": driver format name (json-string)
- - Possible values: "blkdebug", "bochs", "cloop", "cow", "dmg",
- "file", "file", "ftp", "ftps", "host_cdrom",
- "host_device", "host_floppy", "http", "https",
- "nbd", "parallels", "qcow", "qcow2", "raw",
- "tftp", "vdi", "vmdk", "vpc", "vvfat"
- - "backing_file": backing file name (json-string, optional)
- - "encrypted": true if encrypted, false otherwise (json-bool)
-
-Example:
-
--> { "execute": "query-block" }
-<- {
- "return":[
- {
- "device":"ide0-hd0",
- "locked":false,
- "removable":false,
- "inserted":{
- "ro":false,
- "drv":"qcow2",
- "encrypted":false,
- "file":"disks/test.img"
- },
- "type":"hd"
- },
- {
- "device":"ide1-cd0",
- "locked":false,
- "removable":true,
- "type":"cdrom"
- },
- {
- "device":"floppy0",
- "locked":false,
- "removable":true,
- "type": "floppy"
- },
- {
- "device":"sd0",
- "locked":false,
- "removable":true,
- "type":"floppy"
- }
- ]
- }
-
-EQMP
-
-STEXI
@item info blockstats
show block device statistics
-ETEXI
-SQMP
-query-blockstats
-----------------
-
-Show block device statistics.
-
-Each device statistic information is stored in a json-object and the returned
-value is a json-array of all devices.
-
-Each json-object contain the following:
-
-- "device": device name (json-string)
-- "stats": A json-object with the statistics information, it contains:
- - "rd_bytes": bytes read (json-int)
- - "wr_bytes": bytes written (json-int)
- - "rd_operations": read operations (json-int)
- - "wr_operations": write operations (json-int)
- - "wr_highest_offset": Highest offset of a sector written since the
- BlockDriverState has been opened (json-int)
-- "parent": Contains recursively the statistics of the underlying
- protocol (e.g. the host file for a qcow2 image). If there is
- no underlying protocol, this field is omitted
- (json-object, optional)
-
-Example:
-
--> { "execute": "query-blockstats" }
-<- {
- "return":[
- {
- "device":"ide0-hd0",
- "parent":{
- "stats":{
- "wr_highest_offset":3686448128,
- "wr_bytes":9786368,
- "wr_operations":751,
- "rd_bytes":122567168,
- "rd_operations":36772
- }
- },
- "stats":{
- "wr_highest_offset":2821110784,
- "wr_bytes":9786368,
- "wr_operations":692,
- "rd_bytes":122739200,
- "rd_operations":36604
- }
- },
- {
- "device":"ide1-cd0",
- "stats":{
- "wr_highest_offset":0,
- "wr_bytes":0,
- "wr_operations":0,
- "rd_bytes":0,
- "rd_operations":0
- }
- },
- {
- "device":"floppy0",
- "stats":{
- "wr_highest_offset":0,
- "wr_bytes":0,
- "wr_operations":0,
- "rd_bytes":0,
- "rd_operations":0
- }
- },
- {
- "device":"sd0",
- "stats":{
- "wr_highest_offset":0,
- "wr_bytes":0,
- "wr_operations":0,
- "rd_bytes":0,
- "rd_operations":0
- }
- }
- ]
- }
-
-EQMP
-
-STEXI
@item info registers
show the cpu registers
@item info cpus
show infos for each CPU
-ETEXI
-SQMP
-query-cpus
-----------
-
-Show CPU information.
-
-Return a json-array. Each CPU is represented by a json-object, which contains:
-
-- "CPU": CPU index (json-int)
-- "current": true if this is the current CPU, false otherwise (json-bool)
-- "halted": true if the cpu is halted, false otherwise (json-bool)
-- Current program counter. The key's name depends on the architecture:
- "pc": i386/x86_64 (json-int)
- "nip": PPC (json-int)
- "pc" and "npc": sparc (json-int)
- "PC": mips (json-int)
-
-Example:
-
--> { "execute": "query-cpus" }
-<- {
- "return":[
- {
- "CPU":0,
- "current":true,
- "halted":false,
- "pc":3227107138
- },
- {
- "CPU":1,
- "current":false,
- "halted":true,
- "pc":7108165
- }
- ]
- }
-
-EQMP
-
-STEXI
@item info history
show the command line history
@item info irq
show the interrupts statistics (if available)
@item info pic
show i8259 (PIC) state
-ETEXI
-
-STEXI
@item info pci
show emulated PCI device info
-ETEXI
-SQMP
-query-pci
----------
-
-PCI buses and devices information.
-
-The returned value is a json-array of all buses. Each bus is represented by
-a json-object, which has a key with a json-array of all PCI devices attached
-to it. Each device is represented by a json-object.
-
-The bus json-object contains the following:
-
-- "bus": bus number (json-int)
-- "devices": a json-array of json-objects, each json-object represents a
- PCI device
-
-The PCI device json-object contains the following:
-
-- "bus": identical to the parent's bus number (json-int)
-- "slot": slot number (json-int)
-- "function": function number (json-int)
-- "class_info": a json-object containing:
- - "desc": device class description (json-string, optional)
- - "class": device class number (json-int)
-- "id": a json-object containing:
- - "device": device ID (json-int)
- - "vendor": vendor ID (json-int)
-- "irq": device's IRQ if assigned (json-int, optional)
-- "qdev_id": qdev id string (json-string)
-- "pci_bridge": It's a json-object, only present if this device is a
- PCI bridge, contains:
- - "bus": bus number (json-int)
- - "secondary": secondary bus number (json-int)
- - "subordinate": subordinate bus number (json-int)
- - "io_range": I/O memory range information, a json-object with the
- following members:
- - "base": base address, in bytes (json-int)
- - "limit": limit address, in bytes (json-int)
- - "memory_range": memory range information, a json-object with the
- following members:
- - "base": base address, in bytes (json-int)
- - "limit": limit address, in bytes (json-int)
- - "prefetchable_range": Prefetchable memory range information, a
- json-object with the following members:
- - "base": base address, in bytes (json-int)
- - "limit": limit address, in bytes (json-int)
- - "devices": a json-array of PCI devices if there's any attached, each
- each element is represented by a json-object, which contains
- the same members of the 'PCI device json-object' described
- above (optional)
-- "regions": a json-array of json-objects, each json-object represents a
- memory region of this device
-
-The memory range json-object contains the following:
-
-- "base": base memory address (json-int)
-- "limit": limit value (json-int)
-
-The region json-object can be an I/O region or a memory region, an I/O region
-json-object contains the following:
-
-- "type": "io" (json-string, fixed)
-- "bar": BAR number (json-int)
-- "address": memory address (json-int)
-- "size": memory size (json-int)
-
-A memory region json-object contains the following:
-
-- "type": "memory" (json-string, fixed)
-- "bar": BAR number (json-int)
-- "address": memory address (json-int)
-- "size": memory size (json-int)
-- "mem_type_64": true or false (json-bool)
-- "prefetch": true or false (json-bool)
-
-Example:
-
--> { "execute": "query-pci" }
-<- {
- "return":[
- {
- "bus":0,
- "devices":[
- {
- "bus":0,
- "qdev_id":"",
- "slot":0,
- "class_info":{
- "class":1536,
- "desc":"Host bridge"
- },
- "id":{
- "device":32902,
- "vendor":4663
- },
- "function":0,
- "regions":[
-
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "slot":1,
- "class_info":{
- "class":1537,
- "desc":"ISA bridge"
- },
- "id":{
- "device":32902,
- "vendor":28672
- },
- "function":0,
- "regions":[
-
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "slot":1,
- "class_info":{
- "class":257,
- "desc":"IDE controller"
- },
- "id":{
- "device":32902,
- "vendor":28688
- },
- "function":1,
- "regions":[
- {
- "bar":4,
- "size":16,
- "address":49152,
- "type":"io"
- }
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "slot":2,
- "class_info":{
- "class":768,
- "desc":"VGA controller"
- },
- "id":{
- "device":4115,
- "vendor":184
- },
- "function":0,
- "regions":[
- {
- "prefetch":true,
- "mem_type_64":false,
- "bar":0,
- "size":33554432,
- "address":4026531840,
- "type":"memory"
- },
- {
- "prefetch":false,
- "mem_type_64":false,
- "bar":1,
- "size":4096,
- "address":4060086272,
- "type":"memory"
- },
- {
- "prefetch":false,
- "mem_type_64":false,
- "bar":6,
- "size":65536,
- "address":-1,
- "type":"memory"
- }
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "irq":11,
- "slot":4,
- "class_info":{
- "class":1280,
- "desc":"RAM controller"
- },
- "id":{
- "device":6900,
- "vendor":4098
- },
- "function":0,
- "regions":[
- {
- "bar":0,
- "size":32,
- "address":49280,
- "type":"io"
- }
- ]
- }
- ]
- }
- ]
- }
-
-Note: This example has been shortened as the real response is too long.
-
-EQMP
-
-STEXI
@item info tlb
show virtual to physical memory mappings (i386 only)
@item info mem
show the active virtual memory mappings (i386 only)
-ETEXI
-
-STEXI
@item info jit
show dynamic compiler info
@item info kvm
show KVM information
@item info numa
show NUMA information
-ETEXI
-
-STEXI
@item info kvm
show KVM information
-ETEXI
-SQMP
-query-kvm
----------
-
-Show KVM information.
-
-Return a json-object with the following information:
-
-- "enabled": true if KVM support is enabled, false otherwise (json-bool)
-- "present": true if QEMU has KVM support, false otherwise (json-bool)
-
-Example:
-
--> { "execute": "query-kvm" }
-<- { "return": { "enabled": true, "present": true } }
-
-EQMP
-
-STEXI
@item info usb
show USB devices plugged on the virtual USB hub
@item info usbhost
@@ -2248,307 +1173,26 @@ show profiling information
show information about active capturing
@item info snapshots
show list of VM snapshots
-ETEXI
-
-STEXI
@item info status
show the current VM status (running|paused)
-ETEXI
-SQMP
-query-status
-------------
-
-Return a json-object with the following information:
-
-- "running": true if the VM is running, or false if it is paused (json-bool)
-- "singlestep": true if the VM is in single step mode,
- false otherwise (json-bool)
-
-Example:
-
--> { "execute": "query-status" }
-<- { "return": { "running": true, "singlestep": false } }
-
-EQMP
-
-STEXI
@item info pcmcia
show guest PCMCIA status
-ETEXI
-
-STEXI
@item info mice
show which guest mouse is receiving events
-ETEXI
-SQMP
-query-mice
-----------
-
-Show VM mice information.
-
-Each mouse is represented by a json-object, the returned value is a json-array
-of all mice.
-
-The mouse json-object contains the following:
-
-- "name": mouse's name (json-string)
-- "index": mouse's index (json-int)
-- "current": true if this mouse is receiving events, false otherwise (json-bool)
-- "absolute": true if the mouse generates absolute input events (json-bool)
-
-Example:
-
--> { "execute": "query-mice" }
-<- {
- "return":[
- {
- "name":"QEMU Microsoft Mouse",
- "index":0,
- "current":false,
- "absolute":false
- },
- {
- "name":"QEMU PS/2 Mouse",
- "index":1,
- "current":true,
- "absolute":true
- }
- ]
- }
-
-EQMP
-
-STEXI
@item info vnc
show the vnc server status
-ETEXI
-SQMP
-query-vnc
----------
-
-Show VNC server information.
-
-Return a json-object with server information. Connected clients are returned
-as a json-array of json-objects.
-
-The main json-object contains the following:
-
-- "enabled": true or false (json-bool)
-- "host": server's IP address (json-string)
-- "family": address family (json-string)
- - Possible values: "ipv4", "ipv6", "unix", "unknown"
-- "service": server's port number (json-string)
-- "auth": authentication method (json-string)
- - Possible values: "invalid", "none", "ra2", "ra2ne", "sasl", "tight",
- "tls", "ultra", "unknown", "vencrypt", "vencrypt",
- "vencrypt+plain", "vencrypt+tls+none",
- "vencrypt+tls+plain", "vencrypt+tls+sasl",
- "vencrypt+tls+vnc", "vencrypt+x509+none",
- "vencrypt+x509+plain", "vencrypt+x509+sasl",
- "vencrypt+x509+vnc", "vnc"
-- "clients": a json-array of all connected clients
-
-Clients are described by a json-object, each one contain the following:
-
-- "host": client's IP address (json-string)
-- "family": address family (json-string)
- - Possible values: "ipv4", "ipv6", "unix", "unknown"
-- "service": client's port number (json-string)
-- "x509_dname": TLS dname (json-string, optional)
-- "sasl_username": SASL username (json-string, optional)
-
-Example:
-
--> { "execute": "query-vnc" }
-<- {
- "return":{
- "enabled":true,
- "host":"0.0.0.0",
- "service":"50402",
- "auth":"vnc",
- "family":"ipv4",
- "clients":[
- {
- "host":"127.0.0.1",
- "service":"50401",
- "family":"ipv4"
- }
- ]
- }
- }
-
-EQMP
-
-STEXI
@item info name
show the current VM name
-ETEXI
-SQMP
-query-name
-----------
-
-Show VM name.
-
-Return a json-object with the following information:
-
-- "name": VM's name (json-string, optional)
-
-Example:
-
--> { "execute": "query-name" }
-<- { "return": { "name": "qemu-name" } }
-
-EQMP
-
-STEXI
@item info uuid
show the current VM UUID
-ETEXI
-SQMP
-query-uuid
-----------
-
-Show VM UUID.
-
-Return a json-object with the following information:
-
-- "UUID": Universally Unique Identifier (json-string)
-
-Example:
-
--> { "execute": "query-uuid" }
-<- { "return": { "UUID": "550e8400-e29b-41d4-a716-446655440000" } }
-
-EQMP
-
-STEXI
@item info cpustats
show CPU statistics
@item info usernet
show user network stack connection states
-ETEXI
-
-STEXI
@item info migrate
show migration status
-ETEXI
-SQMP
-query-migrate
--------------
-
-Migration status.
-
-Return a json-object. If migration is active there will be another json-object
-with RAM migration status and if block migration is active another one with
-block migration status.
-
-The main json-object contains the following:
-
-- "status": migration status (json-string)
- - Possible values: "active", "completed", "failed", "cancelled"
-- "ram": only present if "status" is "active", it is a json-object with the
- following RAM information (in bytes):
- - "transferred": amount transferred (json-int)
- - "remaining": amount remaining (json-int)
- - "total": total (json-int)
-- "disk": only present if "status" is "active" and it is a block migration,
- it is a json-object with the following disk information (in bytes):
- - "transferred": amount transferred (json-int)
- - "remaining": amount remaining (json-int)
- - "total": total (json-int)
-
-Examples:
-
-1. Before the first migration
-
--> { "execute": "query-migrate" }
-<- { "return": {} }
-
-2. Migration is done and has succeeded
-
--> { "execute": "query-migrate" }
-<- { "return": { "status": "completed" } }
-
-3. Migration is done and has failed
-
--> { "execute": "query-migrate" }
-<- { "return": { "status": "failed" } }
-
-4. Migration is being performed and is not a block migration:
-
--> { "execute": "query-migrate" }
-<- {
- "return":{
- "status":"active",
- "ram":{
- "transferred":123,
- "remaining":123,
- "total":246
- }
- }
- }
-
-5. Migration is being performed and is a block migration:
-
--> { "execute": "query-migrate" }
-<- {
- "return":{
- "status":"active",
- "ram":{
- "total":1057024,
- "remaining":1053304,
- "transferred":3720
- },
- "disk":{
- "total":20971520,
- "remaining":20880384,
- "transferred":91136
- }
- }
- }
-
-EQMP
-
-STEXI
@item info balloon
show balloon information
-ETEXI
-SQMP
-query-balloon
--------------
-
-Show balloon information.
-
-Make an asynchronous request for balloon info. When the request completes a
-json-object will be returned containing the following data:
-
-- "actual": current balloon value in bytes (json-int)
-- "mem_swapped_in": Amount of memory swapped in bytes (json-int, optional)
-- "mem_swapped_out": Amount of memory swapped out in bytes (json-int, optional)
-- "major_page_faults": Number of major faults (json-int, optional)
-- "minor_page_faults": Number of minor faults (json-int, optional)
-- "free_mem": Total amount of free and unused memory in
- bytes (json-int, optional)
-- "total_mem": Total amount of available memory in bytes (json-int, optional)
-
-Example:
-
--> { "execute": "query-balloon" }
-<- {
- "return":{
- "actual":1073741824,
- "mem_swapped_in":0,
- "mem_swapped_out":0,
- "major_page_faults":142,
- "minor_page_faults":239245,
- "free_mem":1014185984,
- "total_mem":1044668416
- }
- }
-
-EQMP
-
-STEXI
@item info qtree
show device tree
@item info qdm
@@ -2567,8 +1211,6 @@ show available trace events and their state
ETEXI
#endif
-HXCOMM DO NOT add new commands after 'info', move your addition before it!
-
STEXI
@end table
ETEXI
commit d1249eaa4b5af2a66b56ceb59b484c6337c3e3c7
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Mon Sep 13 14:44:27 2010 -0300
QMP: Small cleanup in handle_qmp_command()
QMP has its own dispatch tables, we can now drop the following
checks:
o 'info' command: this command doesn't exist in QMP's
dispatch table, the right thing will happen when it's
issued by a client (ie. command not found error)
o monitor_handler_ported(): all QMP handlers are 'ported', no
need to check for that
o monitor_cmd_user_only(): no HMP handler will exist in QMP's
dispatch tables, that's why we have split them after all :-)
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 612ee56..6e62643 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4472,19 +4472,13 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
- /*
- * XXX: We need this special case until QMP has its own dispatch table
- */
- if (compare_cmd(cmd_name, "info")) {
- qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
- goto err_out;
- } else if (strstart(cmd_name, "query-", &query_cmd)) {
+ if (strstart(cmd_name, "query-", &query_cmd)) {
cmd = qmp_find_query_cmd(query_cmd);
} else {
cmd = qmp_find_cmd(cmd_name);
}
- if (!cmd || !monitor_handler_ported(cmd) || monitor_cmd_user_only(cmd)) {
+ if (!cmd) {
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_out;
}
commit 2e061a7c86d77c599676d89c3461f8efe9c275b1
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Thu Sep 16 10:36:54 2010 -0300
QMP: Simplify do_info_commands()
We now iterate over QMP's dispatch tables, no need to check for
QMP-only handlers anymore.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index bf5da50..612ee56 100644
--- a/monitor.c
+++ b/monitor.c
@@ -749,18 +749,13 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
cmd_list = qlist_new();
for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
- if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd) &&
- !compare_cmd(cmd->name, "info")) {
- qlist_append_obj(cmd_list, get_cmd_dict(cmd->name));
- }
+ qlist_append_obj(cmd_list, get_cmd_dict(cmd->name));
}
for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) {
- if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd)) {
- char buf[128];
- snprintf(buf, sizeof(buf), "query-%s", cmd->name);
- qlist_append_obj(cmd_list, get_cmd_dict(buf));
- }
+ char buf[128];
+ snprintf(buf, sizeof(buf), "query-%s", cmd->name);
+ qlist_append_obj(cmd_list, get_cmd_dict(buf));
}
*ret_data = QOBJECT(cmd_list);
commit 3e12a751edcced7ad40c3b87d9784ffcfe941dcc
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Wed Sep 15 17:20:33 2010 -0300
QMP: Introduce query commands dispatch table
The new table is a copy of HMP's table, containing only QObject
handlers.
In the near future HMP will be making QMP calls and then we will
be able to drop QObject handlers from HMP's table.
From now on, QMP and HMP have different query command dispatch
tables.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 06141a5..bf5da50 100644
--- a/monitor.c
+++ b/monitor.c
@@ -190,6 +190,7 @@ static const mon_cmd_t mon_cmds[];
static const mon_cmd_t info_cmds[];
static const mon_cmd_t qmp_cmds[];
+static const mon_cmd_t qmp_query_cmds[];
Monitor *cur_mon;
Monitor *default_mon;
@@ -754,7 +755,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
}
}
- for (cmd = info_cmds; cmd->name != NULL; cmd++) {
+ for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) {
if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd)) {
char buf[128];
snprintf(buf, sizeof(buf), "query-%s", cmd->name);
@@ -2642,6 +2643,131 @@ static const mon_cmd_t qmp_cmds[] = {
{ /* NULL */ },
};
+static const mon_cmd_t qmp_query_cmds[] = {
+ {
+ .name = "version",
+ .args_type = "",
+ .params = "",
+ .help = "show the version of QEMU",
+ .user_print = do_info_version_print,
+ .mhandler.info_new = do_info_version,
+ },
+ {
+ .name = "commands",
+ .args_type = "",
+ .params = "",
+ .help = "list QMP available commands",
+ .user_print = monitor_user_noop,
+ .mhandler.info_new = do_info_commands,
+ },
+ {
+ .name = "chardev",
+ .args_type = "",
+ .params = "",
+ .help = "show the character devices",
+ .user_print = qemu_chr_info_print,
+ .mhandler.info_new = qemu_chr_info,
+ },
+ {
+ .name = "block",
+ .args_type = "",
+ .params = "",
+ .help = "show the block devices",
+ .user_print = bdrv_info_print,
+ .mhandler.info_new = bdrv_info,
+ },
+ {
+ .name = "blockstats",
+ .args_type = "",
+ .params = "",
+ .help = "show block device statistics",
+ .user_print = bdrv_stats_print,
+ .mhandler.info_new = bdrv_info_stats,
+ },
+ {
+ .name = "cpus",
+ .args_type = "",
+ .params = "",
+ .help = "show infos for each CPU",
+ .user_print = monitor_print_cpus,
+ .mhandler.info_new = do_info_cpus,
+ },
+ {
+ .name = "pci",
+ .args_type = "",
+ .params = "",
+ .help = "show PCI info",
+ .user_print = do_pci_info_print,
+ .mhandler.info_new = do_pci_info,
+ },
+ {
+ .name = "kvm",
+ .args_type = "",
+ .params = "",
+ .help = "show KVM information",
+ .user_print = do_info_kvm_print,
+ .mhandler.info_new = do_info_kvm,
+ },
+ {
+ .name = "status",
+ .args_type = "",
+ .params = "",
+ .help = "show the current VM status (running|paused)",
+ .user_print = do_info_status_print,
+ .mhandler.info_new = do_info_status,
+ },
+ {
+ .name = "mice",
+ .args_type = "",
+ .params = "",
+ .help = "show which guest mouse is receiving events",
+ .user_print = do_info_mice_print,
+ .mhandler.info_new = do_info_mice,
+ },
+ {
+ .name = "vnc",
+ .args_type = "",
+ .params = "",
+ .help = "show the vnc server status",
+ .user_print = do_info_vnc_print,
+ .mhandler.info_new = do_info_vnc,
+ },
+ {
+ .name = "name",
+ .args_type = "",
+ .params = "",
+ .help = "show the current VM name",
+ .user_print = do_info_name_print,
+ .mhandler.info_new = do_info_name,
+ },
+ {
+ .name = "uuid",
+ .args_type = "",
+ .params = "",
+ .help = "show the current VM UUID",
+ .user_print = do_info_uuid_print,
+ .mhandler.info_new = do_info_uuid,
+ },
+ {
+ .name = "migrate",
+ .args_type = "",
+ .params = "",
+ .help = "show migration status",
+ .user_print = do_info_migrate_print,
+ .mhandler.info_new = do_info_migrate,
+ },
+ {
+ .name = "balloon",
+ .args_type = "",
+ .params = "",
+ .help = "show balloon information",
+ .user_print = monitor_print_balloon,
+ .mhandler.info_async = do_info_balloon,
+ .flags = MONITOR_CMD_ASYNC,
+ },
+ { /* NULL */ },
+};
+
/*******************************************************************/
static const char *pch;
@@ -3369,7 +3495,7 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname)
static const mon_cmd_t *qmp_find_query_cmd(const char *info_item)
{
- return search_dispatch_table(info_cmds, info_item);
+ return search_dispatch_table(qmp_query_cmds, info_item);
}
static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
commit f36b4afba9fe6ab5adefef9ca67521a5f677fccc
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Wed Sep 15 17:17:45 2010 -0300
QMP: Introduce command dispatch table
Also update QMP functions to use it. The table is generated
from the qmp-commands.hx file.
From now on, QMP and HMP have different command dispatch
tables.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/Makefile.target b/Makefile.target
index 91d0381..3a1fa7e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -307,7 +307,7 @@ obj-alpha-y = alpha_palcode.o
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
-monitor.o: qemu-monitor.h
+monitor.o: qemu-monitor.h qmp-commands.h
$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
@@ -331,10 +331,13 @@ gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
qemu-monitor.h: $(SRC_PATH)/qemu-monitor.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
+qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
+ $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
+
clean:
rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
rm -f *.d */*.d tcg/*.o ide/*.o
- rm -f qemu-monitor.h gdbstub-xml.c
+ rm -f qemu-monitor.h qmp-commands.h gdbstub-xml.c
install: all
ifneq ($(PROGS),)
diff --git a/monitor.c b/monitor.c
index f62c34a..06141a5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -189,6 +189,8 @@ static QLIST_HEAD(mon_list, Monitor) mon_list;
static const mon_cmd_t mon_cmds[];
static const mon_cmd_t info_cmds[];
+static const mon_cmd_t qmp_cmds[];
+
Monitor *cur_mon;
Monitor *default_mon;
@@ -745,7 +747,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
cmd_list = qlist_new();
- for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
+ for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd) &&
!compare_cmd(cmd->name, "info")) {
qlist_append_obj(cmd_list, get_cmd_dict(cmd->name));
@@ -2635,6 +2637,11 @@ static const mon_cmd_t info_cmds[] = {
},
};
+static const mon_cmd_t qmp_cmds[] = {
+#include "qmp-commands.h"
+ { /* NULL */ },
+};
+
/*******************************************************************/
static const char *pch;
@@ -3367,7 +3374,7 @@ static const mon_cmd_t *qmp_find_query_cmd(const char *info_item)
static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
{
- return search_dispatch_table(mon_cmds, cmdname);
+ return search_dispatch_table(qmp_cmds, cmdname);
}
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
commit bead3ce139025797a7e970f7d2c43e61a60a7c48
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Wed Sep 15 17:08:39 2010 -0300
QMP: Introduce qmp_find_cmd()
Next commit needs this new function: it will introduce the
the QMP's command dispatch table and qmp_find_cmd() will be
used to search on it.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index f0854c4..f62c34a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3365,6 +3365,11 @@ static const mon_cmd_t *qmp_find_query_cmd(const char *info_item)
return search_dispatch_table(info_cmds, info_item);
}
+static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
+{
+ return search_dispatch_table(mon_cmds, cmdname);
+}
+
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
const char *cmdline,
QDict *qdict)
@@ -4348,7 +4353,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
} else if (strstart(cmd_name, "query-", &query_cmd)) {
cmd = qmp_find_query_cmd(query_cmd);
} else {
- cmd = monitor_find_command(cmd_name);
+ cmd = qmp_find_cmd(cmd_name);
}
if (!cmd || !monitor_handler_ported(cmd) || monitor_cmd_user_only(cmd)) {
commit 82a56f0d83d4bca92bbe8b0546cb70292c1dc65d
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Mon Sep 13 12:26:00 2010 -0300
Monitor: Introduce the qmp-commands.hx file
This file contains a copy of the following information from the
qemu-monitor.hx file:
o QObject handlers entries
o QMP documentation (all SQMP/EQMP sections)
Right now it's only used to generate the QMP docs in QMP/, but
next commits will turn this into QMP's command dispatch table.
It's important to note that QObject handlers entries are going
to get duplicated: they will exist in both QMP's and HMP's
dispatch tables.
This will be fixed in the near future, when we add a proper
QMP call interface and HMP is converted to use it. This way we
can completely drop QObject handlers entries from HMP's tables.
NOTE: HMP specific constructions, like "q|quit", have been dropped.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/Makefile b/Makefile
index fca1e7a..938d88b 100644
--- a/Makefile
+++ b/Makefile
@@ -252,7 +252,7 @@ qemu-options.texi: $(SRC_PATH)/qemu-options.hx
qemu-monitor.texi: $(SRC_PATH)/qemu-monitor.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@")
-QMP/qmp-commands.txt: $(SRC_PATH)/qemu-monitor.hx
+QMP/qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -q < $< > $@," GEN $@")
qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx
diff --git a/QMP/README b/QMP/README
index 948d445..7e2b51a 100644
--- a/QMP/README
+++ b/QMP/README
@@ -82,7 +82,7 @@ doing any code change. This is so because:
2. Review can improve your interface. Letting that happen before
you implement it can save you work.
-* The qmp-commands.txt file is generated from the qemu-monitor.hx one, which
+* The qmp-commands.txt file is generated from the qmp-commands.hx one, which
is the file that should be edited.
Homepage
diff --git a/qmp-commands.hx b/qmp-commands.hx
new file mode 100644
index 0000000..793cf1c
--- /dev/null
+++ b/qmp-commands.hx
@@ -0,0 +1,1541 @@
+HXCOMM QMP dispatch table and documentation
+HXCOMM Text between SQMP and EQMP is copied to the QMP documention file and
+HXCOMM does not show up in the other formats.
+
+SQMP
+ QMP Supported Commands
+ ----------------------
+
+This document describes all commands currently supported by QMP.
+
+Most of the time their usage is exactly the same as in the user Monitor, this
+means that any other document which also describe commands (the manpage,
+QEMU's manual, etc) can and should be consulted.
+
+QMP has two types of commands: regular and query commands. Regular commands
+usually change the Virtual Machine's state someway, while query commands just
+return information. The sections below are divided accordingly.
+
+It's important to observe that all communication examples are formatted in
+a reader-friendly way, so that they're easier to understand. However, in real
+protocol usage, they're emitted as a single line.
+
+Also, the following notation is used to denote data flow:
+
+-> data issued by the Client
+<- Server data response
+
+Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed
+information on the Server command and response formats.
+
+NOTE: This document is temporary and will be replaced soon.
+
+1. Stability Considerations
+===========================
+
+The current QMP command set (described in this file) may be useful for a
+number of use cases, however it's limited and several commands have bad
+defined semantics, specially with regard to command completion.
+
+These problems are going to be solved incrementally in the next QEMU releases
+and we're going to establish a deprecation policy for badly defined commands.
+
+If you're planning to adopt QMP, please observe the following:
+
+ 1. The deprecation policy will take efect and be documented soon, please
+ check the documentation of each used command as soon as a new release of
+ QEMU is available
+
+ 2. DO NOT rely on anything which is not explicit documented
+
+ 3. Errors, in special, are not documented. Applications should NOT check
+ for specific errors classes or data (it's strongly recommended to only
+ check for the "error" key)
+
+2. Regular Commands
+===================
+
+Server's responses in the examples below are always a success response, please
+refer to the QMP specification for more details on error responses.
+
+EQMP
+
+ {
+ .name = "quit",
+ .args_type = "",
+ .params = "",
+ .help = "quit the emulator",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_quit,
+ },
+
+SQMP
+quit
+----
+
+Quit the emulator.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "quit" }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "eject",
+ .args_type = "force:-f,device:B",
+ .params = "[-f] device",
+ .help = "eject a removable medium (use -f to force it)",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_eject,
+ },
+
+SQMP
+eject
+-----
+
+Eject a removable medium.
+
+Arguments:
+
+- force: force ejection (json-bool, optional)
+- device: device name (json-string)
+
+Example:
+
+-> { "execute": "eject", "arguments": { "device": "ide1-cd0" } }
+<- { "return": {} }
+
+Note: The "force" argument defaults to false.
+
+EQMP
+
+ {
+ .name = "change",
+ .args_type = "device:B,target:F,arg:s?",
+ .params = "device filename [format]",
+ .help = "change a removable medium, optional format",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_change,
+ },
+
+SQMP
+change
+------
+
+Change a removable medium or VNC configuration.
+
+Arguments:
+
+- "device": device name (json-string)
+- "target": filename or item (json-string)
+- "arg": additional argument (json-string, optional)
+
+Examples:
+
+1. Change a removable medium
+
+-> { "execute": "change",
+ "arguments": { "device": "ide1-cd0",
+ "target": "/srv/images/Fedora-12-x86_64-DVD.iso" } }
+<- { "return": {} }
+
+2. Change VNC password
+
+-> { "execute": "change",
+ "arguments": { "device": "vnc", "target": "password",
+ "arg": "foobar1" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "screendump",
+ .args_type = "filename:F",
+ .params = "filename",
+ .help = "save screen into PPM image 'filename'",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_screen_dump,
+ },
+
+SQMP
+screendump
+----------
+
+Save screen into PPM image.
+
+Arguments:
+
+- "filename": file path (json-string)
+
+Example:
+
+-> { "execute": "screendump", "arguments": { "filename": "/tmp/image" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "stop",
+ .args_type = "",
+ .params = "",
+ .help = "stop emulation",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_stop,
+ },
+
+SQMP
+stop
+----
+
+Stop the emulator.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "stop" }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "cont",
+ .args_type = "",
+ .params = "",
+ .help = "resume emulation",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_cont,
+ },
+
+SQMP
+cont
+----
+
+Resume emulation.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "cont" }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "system_reset",
+ .args_type = "",
+ .params = "",
+ .help = "reset the system",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_system_reset,
+ },
+
+SQMP
+system_reset
+------------
+
+Reset the system.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "system_reset" }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "system_powerdown",
+ .args_type = "",
+ .params = "",
+ .help = "send system power down event",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_system_powerdown,
+ },
+
+SQMP
+system_powerdown
+----------------
+
+Send system power down event.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "system_powerdown" }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "device_add",
+ .args_type = "device:O",
+ .params = "driver[,prop=value][,...]",
+ .help = "add device, like -device on the command line",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_device_add,
+ },
+
+SQMP
+device_add
+----------
+
+Add a device.
+
+Arguments:
+
+- "driver": the name of the new device's driver (json-string)
+- "bus": the device's parent bus (device tree path, json-string, optional)
+- "id": the device's ID, must be unique (json-string)
+- device properties
+
+Example:
+
+-> { "execute": "device_add", "arguments": { "driver": "e1000", "id": "net1" } }
+<- { "return": {} }
+
+Notes:
+
+(1) For detailed information about this command, please refer to the
+ 'docs/qdev-device-use.txt' file.
+
+(2) It's possible to list device properties by running QEMU with the
+ "-device DEVICE,\?" command-line argument, where DEVICE is the device's name
+
+EQMP
+
+ {
+ .name = "device_del",
+ .args_type = "id:s",
+ .params = "device",
+ .help = "remove device",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_device_del,
+ },
+
+SQMP
+device_del
+----------
+
+Remove a device.
+
+Arguments:
+
+- "id": the device's ID (json-string)
+
+Example:
+
+-> { "execute": "device_del", "arguments": { "id": "net1" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "cpu",
+ .args_type = "index:i",
+ .params = "index",
+ .help = "set the default CPU",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_cpu_set,
+ },
+
+SQMP
+cpu
+---
+
+Set the default CPU.
+
+Arguments:
+
+- "index": the CPU's index (json-int)
+
+Example:
+
+-> { "execute": "cpu", "arguments": { "index": 0 } }
+<- { "return": {} }
+
+Note: CPUs' indexes are obtained with the 'query-cpus' command.
+
+EQMP
+
+ {
+ .name = "memsave",
+ .args_type = "val:l,size:i,filename:s",
+ .params = "addr size file",
+ .help = "save to disk virtual memory dump starting at 'addr' of size 'size'",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_memory_save,
+ },
+
+SQMP
+memsave
+-------
+
+Save to disk virtual memory dump starting at 'val' of size 'size'.
+
+Arguments:
+
+- "val": the starting address (json-int)
+- "size": the memory size, in bytes (json-int)
+- "filename": file path (json-string)
+
+Example:
+
+-> { "execute": "memsave",
+ "arguments": { "val": 10,
+ "size": 100,
+ "filename": "/tmp/virtual-mem-dump" } }
+<- { "return": {} }
+
+Note: Depends on the current CPU.
+
+EQMP
+
+ {
+ .name = "pmemsave",
+ .args_type = "val:l,size:i,filename:s",
+ .params = "addr size file",
+ .help = "save to disk physical memory dump starting at 'addr' of size 'size'",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_physical_memory_save,
+ },
+
+SQMP
+pmemsave
+--------
+
+Save to disk physical memory dump starting at 'val' of size 'size'.
+
+Arguments:
+
+- "val": the starting address (json-int)
+- "size": the memory size, in bytes (json-int)
+- "filename": file path (json-string)
+
+Example:
+
+-> { "execute": "pmemsave",
+ "arguments": { "val": 10,
+ "size": 100,
+ "filename": "/tmp/physical-mem-dump" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "migrate",
+ .args_type = "detach:-d,blk:-b,inc:-i,uri:s",
+ .params = "[-d] [-b] [-i] uri",
+ .help = "migrate to URI (using -d to not wait for completion)"
+ "\n\t\t\t -b for migration without shared storage with"
+ " full copy of disk\n\t\t\t -i for migration without "
+ "shared storage with incremental copy of disk "
+ "(base image shared between src and destination)",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate,
+ },
+
+SQMP
+migrate
+-------
+
+Migrate to URI.
+
+Arguments:
+
+- "blk": block migration, full disk copy (json-bool, optional)
+- "inc": incremental disk copy (json-bool, optional)
+- "uri": Destination URI (json-string)
+
+Example:
+
+-> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } }
+<- { "return": {} }
+
+Notes:
+
+(1) The 'query-migrate' command should be used to check migration's progress
+ and final result (this information is provided by the 'status' member)
+(2) All boolean arguments default to false
+(3) The user Monitor's "detach" argument is invalid in QMP and should not
+ be used
+
+EQMP
+
+ {
+ .name = "migrate_cancel",
+ .args_type = "",
+ .params = "",
+ .help = "cancel the current VM migration",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate_cancel,
+ },
+
+SQMP
+migrate_cancel
+--------------
+
+Cancel the current migration.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "migrate_cancel" }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "migrate_set_speed",
+ .args_type = "value:f",
+ .params = "value",
+ .help = "set maximum speed (in bytes) for migrations",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate_set_speed,
+ },
+
+SQMP
+migrate_set_speed
+-----------------
+
+Set maximum speed for migrations.
+
+Arguments:
+
+- "value": maximum speed, in bytes per second (json-number)
+
+Example:
+
+-> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "migrate_set_downtime",
+ .args_type = "value:T",
+ .params = "value",
+ .help = "set maximum tolerated downtime (in seconds) for migrations",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_migrate_set_downtime,
+ },
+
+SQMP
+migrate_set_downtime
+--------------------
+
+Set maximum tolerated downtime (in seconds) for migrations.
+
+Arguments:
+
+- "value": maximum downtime (json-number)
+
+Example:
+
+-> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "netdev_add",
+ .args_type = "netdev:O",
+ .params = "[user|tap|socket],id=str[,prop=value][,...]",
+ .help = "add host network device",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_netdev_add,
+ },
+
+SQMP
+netdev_add
+----------
+
+Add host network device.
+
+Arguments:
+
+- "type": the device type, "tap", "user", ... (json-string)
+- "id": the device's ID, must be unique (json-string)
+- device options
+
+Example:
+
+-> { "execute": "netdev_add", "arguments": { "type": "user", "id": "netdev1" } }
+<- { "return": {} }
+
+Note: The supported device options are the same ones supported by the '-net'
+ command-line argument, which are listed in the '-help' output or QEMU's
+ manual
+
+EQMP
+
+ {
+ .name = "netdev_del",
+ .args_type = "id:s",
+ .params = "id",
+ .help = "remove host network device",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_netdev_del,
+ },
+
+SQMP
+netdev_del
+----------
+
+Remove host network device.
+
+Arguments:
+
+- "id": the device's ID, must be unique (json-string)
+
+Example:
+
+-> { "execute": "netdev_del", "arguments": { "id": "netdev1" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "balloon",
+ .args_type = "value:M",
+ .params = "target",
+ .help = "request VM to change its memory allocation (in MB)",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_async = do_balloon,
+ .flags = MONITOR_CMD_ASYNC,
+ },
+
+SQMP
+balloon
+-------
+
+Request VM to change its memory allocation (in bytes).
+
+Arguments:
+
+- "value": New memory allocation (json-int)
+
+Example:
+
+-> { "execute": "balloon", "arguments": { "value": 536870912 } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "set_link",
+ .args_type = "name:s,up:b",
+ .params = "name on|off",
+ .help = "change the link status of a network adapter",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_set_link,
+ },
+
+SQMP
+set_link
+--------
+
+Change the link status of a network adapter.
+
+Arguments:
+
+- "name": network device name (json-string)
+- "up": status is up (json-bool)
+
+Example:
+
+-> { "execute": "set_link", "arguments": { "name": "e1000.0", "up": false } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "getfd",
+ .args_type = "fdname:s",
+ .params = "getfd name",
+ .help = "receive a file descriptor via SCM rights and assign it a name",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_getfd,
+ },
+
+SQMP
+getfd
+-----
+
+Receive a file descriptor via SCM rights and assign it a name.
+
+Arguments:
+
+- "fdname": file descriptor name (json-string)
+
+Example:
+
+-> { "execute": "getfd", "arguments": { "fdname": "fd1" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "closefd",
+ .args_type = "fdname:s",
+ .params = "closefd name",
+ .help = "close a file descriptor previously passed via SCM rights",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_closefd,
+ },
+
+SQMP
+closefd
+-------
+
+Close a file descriptor previously passed via SCM rights.
+
+Arguments:
+
+- "fdname": file descriptor name (json-string)
+
+Example:
+
+-> { "execute": "closefd", "arguments": { "fdname": "fd1" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "block_passwd",
+ .args_type = "device:B,password:s",
+ .params = "block_passwd device password",
+ .help = "set the password of encrypted block devices",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_block_set_passwd,
+ },
+
+SQMP
+block_passwd
+------------
+
+Set the password of encrypted block devices.
+
+Arguments:
+
+- "device": device name (json-string)
+- "password": password (json-string)
+
+Example:
+
+-> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0",
+ "password": "12345" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "qmp_capabilities",
+ .args_type = "",
+ .params = "",
+ .help = "enable QMP capabilities",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_qmp_capabilities,
+ },
+
+SQMP
+qmp_capabilities
+----------------
+
+Enable QMP capabilities.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "qmp_capabilities" }
+<- { "return": {} }
+
+Note: This command must be issued before issuing any other command.
+
+3. Query Commands
+=================
+
+HXCOMM Each query command below is inside a SQMP/EQMP section, do NOT change
+HXCOMM this! We will possibly move query commands definitions inside those
+HXCOMM sections, just like regular commands.
+
+EQMP
+
+SQMP
+query-version
+-------------
+
+Show QEMU version.
+
+Return a json-object with the following information:
+
+- "qemu": A json-object containing three integer values:
+ - "major": QEMU's major version (json-int)
+ - "minor": QEMU's minor version (json-int)
+ - "micro": QEMU's micro version (json-int)
+- "package": package's version (json-string)
+
+Example:
+
+-> { "execute": "query-version" }
+<- {
+ "return":{
+ "qemu":{
+ "major":0,
+ "minor":11,
+ "micro":5
+ },
+ "package":""
+ }
+ }
+
+EQMP
+
+SQMP
+query-commands
+--------------
+
+List QMP available commands.
+
+Each command is represented by a json-object, the returned value is a json-array
+of all commands.
+
+Each json-object contain:
+
+- "name": command's name (json-string)
+
+Example:
+
+-> { "execute": "query-commands" }
+<- {
+ "return":[
+ {
+ "name":"query-balloon"
+ },
+ {
+ "name":"system_powerdown"
+ }
+ ]
+ }
+
+Note: This example has been shortened as the real response is too long.
+
+EQMP
+
+SQMP
+query-chardev
+-------------
+
+Each device is represented by a json-object. The returned value is a json-array
+of all devices.
+
+Each json-object contain the following:
+
+- "label": device's label (json-string)
+- "filename": device's file (json-string)
+
+Example:
+
+-> { "execute": "query-chardev" }
+<- {
+ "return":[
+ {
+ "label":"monitor",
+ "filename":"stdio"
+ },
+ {
+ "label":"serial0",
+ "filename":"vc"
+ }
+ ]
+ }
+
+EQMP
+
+SQMP
+query-block
+-----------
+
+Show the block devices.
+
+Each block device information is stored in a json-object and the returned value
+is a json-array of all devices.
+
+Each json-object contain the following:
+
+- "device": device name (json-string)
+- "type": device type (json-string)
+ - Possible values: "hd", "cdrom", "floppy", "unknown"
+- "removable": true if the device is removable, false otherwise (json-bool)
+- "locked": true if the device is locked, false otherwise (json-bool)
+- "inserted": only present if the device is inserted, it is a json-object
+ containing the following:
+ - "file": device file name (json-string)
+ - "ro": true if read-only, false otherwise (json-bool)
+ - "drv": driver format name (json-string)
+ - Possible values: "blkdebug", "bochs", "cloop", "cow", "dmg",
+ "file", "file", "ftp", "ftps", "host_cdrom",
+ "host_device", "host_floppy", "http", "https",
+ "nbd", "parallels", "qcow", "qcow2", "raw",
+ "tftp", "vdi", "vmdk", "vpc", "vvfat"
+ - "backing_file": backing file name (json-string, optional)
+ - "encrypted": true if encrypted, false otherwise (json-bool)
+
+Example:
+
+-> { "execute": "query-block" }
+<- {
+ "return":[
+ {
+ "device":"ide0-hd0",
+ "locked":false,
+ "removable":false,
+ "inserted":{
+ "ro":false,
+ "drv":"qcow2",
+ "encrypted":false,
+ "file":"disks/test.img"
+ },
+ "type":"hd"
+ },
+ {
+ "device":"ide1-cd0",
+ "locked":false,
+ "removable":true,
+ "type":"cdrom"
+ },
+ {
+ "device":"floppy0",
+ "locked":false,
+ "removable":true,
+ "type": "floppy"
+ },
+ {
+ "device":"sd0",
+ "locked":false,
+ "removable":true,
+ "type":"floppy"
+ }
+ ]
+ }
+
+EQMP
+
+SQMP
+query-blockstats
+----------------
+
+Show block device statistics.
+
+Each device statistic information is stored in a json-object and the returned
+value is a json-array of all devices.
+
+Each json-object contain the following:
+
+- "device": device name (json-string)
+- "stats": A json-object with the statistics information, it contains:
+ - "rd_bytes": bytes read (json-int)
+ - "wr_bytes": bytes written (json-int)
+ - "rd_operations": read operations (json-int)
+ - "wr_operations": write operations (json-int)
+ - "wr_highest_offset": Highest offset of a sector written since the
+ BlockDriverState has been opened (json-int)
+- "parent": Contains recursively the statistics of the underlying
+ protocol (e.g. the host file for a qcow2 image). If there is
+ no underlying protocol, this field is omitted
+ (json-object, optional)
+
+Example:
+
+-> { "execute": "query-blockstats" }
+<- {
+ "return":[
+ {
+ "device":"ide0-hd0",
+ "parent":{
+ "stats":{
+ "wr_highest_offset":3686448128,
+ "wr_bytes":9786368,
+ "wr_operations":751,
+ "rd_bytes":122567168,
+ "rd_operations":36772
+ }
+ },
+ "stats":{
+ "wr_highest_offset":2821110784,
+ "wr_bytes":9786368,
+ "wr_operations":692,
+ "rd_bytes":122739200,
+ "rd_operations":36604
+ }
+ },
+ {
+ "device":"ide1-cd0",
+ "stats":{
+ "wr_highest_offset":0,
+ "wr_bytes":0,
+ "wr_operations":0,
+ "rd_bytes":0,
+ "rd_operations":0
+ }
+ },
+ {
+ "device":"floppy0",
+ "stats":{
+ "wr_highest_offset":0,
+ "wr_bytes":0,
+ "wr_operations":0,
+ "rd_bytes":0,
+ "rd_operations":0
+ }
+ },
+ {
+ "device":"sd0",
+ "stats":{
+ "wr_highest_offset":0,
+ "wr_bytes":0,
+ "wr_operations":0,
+ "rd_bytes":0,
+ "rd_operations":0
+ }
+ }
+ ]
+ }
+
+EQMP
+
+SQMP
+query-cpus
+----------
+
+Show CPU information.
+
+Return a json-array. Each CPU is represented by a json-object, which contains:
+
+- "CPU": CPU index (json-int)
+- "current": true if this is the current CPU, false otherwise (json-bool)
+- "halted": true if the cpu is halted, false otherwise (json-bool)
+- Current program counter. The key's name depends on the architecture:
+ "pc": i386/x86_64 (json-int)
+ "nip": PPC (json-int)
+ "pc" and "npc": sparc (json-int)
+ "PC": mips (json-int)
+
+Example:
+
+-> { "execute": "query-cpus" }
+<- {
+ "return":[
+ {
+ "CPU":0,
+ "current":true,
+ "halted":false,
+ "pc":3227107138
+ },
+ {
+ "CPU":1,
+ "current":false,
+ "halted":true,
+ "pc":7108165
+ }
+ ]
+ }
+
+EQMP
+
+SQMP
+query-pci
+---------
+
+PCI buses and devices information.
+
+The returned value is a json-array of all buses. Each bus is represented by
+a json-object, which has a key with a json-array of all PCI devices attached
+to it. Each device is represented by a json-object.
+
+The bus json-object contains the following:
+
+- "bus": bus number (json-int)
+- "devices": a json-array of json-objects, each json-object represents a
+ PCI device
+
+The PCI device json-object contains the following:
+
+- "bus": identical to the parent's bus number (json-int)
+- "slot": slot number (json-int)
+- "function": function number (json-int)
+- "class_info": a json-object containing:
+ - "desc": device class description (json-string, optional)
+ - "class": device class number (json-int)
+- "id": a json-object containing:
+ - "device": device ID (json-int)
+ - "vendor": vendor ID (json-int)
+- "irq": device's IRQ if assigned (json-int, optional)
+- "qdev_id": qdev id string (json-string)
+- "pci_bridge": It's a json-object, only present if this device is a
+ PCI bridge, contains:
+ - "bus": bus number (json-int)
+ - "secondary": secondary bus number (json-int)
+ - "subordinate": subordinate bus number (json-int)
+ - "io_range": I/O memory range information, a json-object with the
+ following members:
+ - "base": base address, in bytes (json-int)
+ - "limit": limit address, in bytes (json-int)
+ - "memory_range": memory range information, a json-object with the
+ following members:
+ - "base": base address, in bytes (json-int)
+ - "limit": limit address, in bytes (json-int)
+ - "prefetchable_range": Prefetchable memory range information, a
+ json-object with the following members:
+ - "base": base address, in bytes (json-int)
+ - "limit": limit address, in bytes (json-int)
+ - "devices": a json-array of PCI devices if there's any attached, each
+ each element is represented by a json-object, which contains
+ the same members of the 'PCI device json-object' described
+ above (optional)
+- "regions": a json-array of json-objects, each json-object represents a
+ memory region of this device
+
+The memory range json-object contains the following:
+
+- "base": base memory address (json-int)
+- "limit": limit value (json-int)
+
+The region json-object can be an I/O region or a memory region, an I/O region
+json-object contains the following:
+
+- "type": "io" (json-string, fixed)
+- "bar": BAR number (json-int)
+- "address": memory address (json-int)
+- "size": memory size (json-int)
+
+A memory region json-object contains the following:
+
+- "type": "memory" (json-string, fixed)
+- "bar": BAR number (json-int)
+- "address": memory address (json-int)
+- "size": memory size (json-int)
+- "mem_type_64": true or false (json-bool)
+- "prefetch": true or false (json-bool)
+
+Example:
+
+-> { "execute": "query-pci" }
+<- {
+ "return":[
+ {
+ "bus":0,
+ "devices":[
+ {
+ "bus":0,
+ "qdev_id":"",
+ "slot":0,
+ "class_info":{
+ "class":1536,
+ "desc":"Host bridge"
+ },
+ "id":{
+ "device":32902,
+ "vendor":4663
+ },
+ "function":0,
+ "regions":[
+
+ ]
+ },
+ {
+ "bus":0,
+ "qdev_id":"",
+ "slot":1,
+ "class_info":{
+ "class":1537,
+ "desc":"ISA bridge"
+ },
+ "id":{
+ "device":32902,
+ "vendor":28672
+ },
+ "function":0,
+ "regions":[
+
+ ]
+ },
+ {
+ "bus":0,
+ "qdev_id":"",
+ "slot":1,
+ "class_info":{
+ "class":257,
+ "desc":"IDE controller"
+ },
+ "id":{
+ "device":32902,
+ "vendor":28688
+ },
+ "function":1,
+ "regions":[
+ {
+ "bar":4,
+ "size":16,
+ "address":49152,
+ "type":"io"
+ }
+ ]
+ },
+ {
+ "bus":0,
+ "qdev_id":"",
+ "slot":2,
+ "class_info":{
+ "class":768,
+ "desc":"VGA controller"
+ },
+ "id":{
+ "device":4115,
+ "vendor":184
+ },
+ "function":0,
+ "regions":[
+ {
+ "prefetch":true,
+ "mem_type_64":false,
+ "bar":0,
+ "size":33554432,
+ "address":4026531840,
+ "type":"memory"
+ },
+ {
+ "prefetch":false,
+ "mem_type_64":false,
+ "bar":1,
+ "size":4096,
+ "address":4060086272,
+ "type":"memory"
+ },
+ {
+ "prefetch":false,
+ "mem_type_64":false,
+ "bar":6,
+ "size":65536,
+ "address":-1,
+ "type":"memory"
+ }
+ ]
+ },
+ {
+ "bus":0,
+ "qdev_id":"",
+ "irq":11,
+ "slot":4,
+ "class_info":{
+ "class":1280,
+ "desc":"RAM controller"
+ },
+ "id":{
+ "device":6900,
+ "vendor":4098
+ },
+ "function":0,
+ "regions":[
+ {
+ "bar":0,
+ "size":32,
+ "address":49280,
+ "type":"io"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+
+Note: This example has been shortened as the real response is too long.
+
+EQMP
+
+SQMP
+query-kvm
+---------
+
+Show KVM information.
+
+Return a json-object with the following information:
+
+- "enabled": true if KVM support is enabled, false otherwise (json-bool)
+- "present": true if QEMU has KVM support, false otherwise (json-bool)
+
+Example:
+
+-> { "execute": "query-kvm" }
+<- { "return": { "enabled": true, "present": true } }
+
+EQMP
+
+SQMP
+query-status
+------------
+
+Return a json-object with the following information:
+
+- "running": true if the VM is running, or false if it is paused (json-bool)
+- "singlestep": true if the VM is in single step mode,
+ false otherwise (json-bool)
+
+Example:
+
+-> { "execute": "query-status" }
+<- { "return": { "running": true, "singlestep": false } }
+
+EQMP
+
+SQMP
+query-mice
+----------
+
+Show VM mice information.
+
+Each mouse is represented by a json-object, the returned value is a json-array
+of all mice.
+
+The mouse json-object contains the following:
+
+- "name": mouse's name (json-string)
+- "index": mouse's index (json-int)
+- "current": true if this mouse is receiving events, false otherwise (json-bool)
+- "absolute": true if the mouse generates absolute input events (json-bool)
+
+Example:
+
+-> { "execute": "query-mice" }
+<- {
+ "return":[
+ {
+ "name":"QEMU Microsoft Mouse",
+ "index":0,
+ "current":false,
+ "absolute":false
+ },
+ {
+ "name":"QEMU PS/2 Mouse",
+ "index":1,
+ "current":true,
+ "absolute":true
+ }
+ ]
+ }
+
+EQMP
+
+SQMP
+query-vnc
+---------
+
+Show VNC server information.
+
+Return a json-object with server information. Connected clients are returned
+as a json-array of json-objects.
+
+The main json-object contains the following:
+
+- "enabled": true or false (json-bool)
+- "host": server's IP address (json-string)
+- "family": address family (json-string)
+ - Possible values: "ipv4", "ipv6", "unix", "unknown"
+- "service": server's port number (json-string)
+- "auth": authentication method (json-string)
+ - Possible values: "invalid", "none", "ra2", "ra2ne", "sasl", "tight",
+ "tls", "ultra", "unknown", "vencrypt", "vencrypt",
+ "vencrypt+plain", "vencrypt+tls+none",
+ "vencrypt+tls+plain", "vencrypt+tls+sasl",
+ "vencrypt+tls+vnc", "vencrypt+x509+none",
+ "vencrypt+x509+plain", "vencrypt+x509+sasl",
+ "vencrypt+x509+vnc", "vnc"
+- "clients": a json-array of all connected clients
+
+Clients are described by a json-object, each one contain the following:
+
+- "host": client's IP address (json-string)
+- "family": address family (json-string)
+ - Possible values: "ipv4", "ipv6", "unix", "unknown"
+- "service": client's port number (json-string)
+- "x509_dname": TLS dname (json-string, optional)
+- "sasl_username": SASL username (json-string, optional)
+
+Example:
+
+-> { "execute": "query-vnc" }
+<- {
+ "return":{
+ "enabled":true,
+ "host":"0.0.0.0",
+ "service":"50402",
+ "auth":"vnc",
+ "family":"ipv4",
+ "clients":[
+ {
+ "host":"127.0.0.1",
+ "service":"50401",
+ "family":"ipv4"
+ }
+ ]
+ }
+ }
+
+EQMP
+
+SQMP
+query-name
+----------
+
+Show VM name.
+
+Return a json-object with the following information:
+
+- "name": VM's name (json-string, optional)
+
+Example:
+
+-> { "execute": "query-name" }
+<- { "return": { "name": "qemu-name" } }
+
+EQMP
+
+SQMP
+query-uuid
+----------
+
+Show VM UUID.
+
+Return a json-object with the following information:
+
+- "UUID": Universally Unique Identifier (json-string)
+
+Example:
+
+-> { "execute": "query-uuid" }
+<- { "return": { "UUID": "550e8400-e29b-41d4-a716-446655440000" } }
+
+EQMP
+
+SQMP
+query-migrate
+-------------
+
+Migration status.
+
+Return a json-object. If migration is active there will be another json-object
+with RAM migration status and if block migration is active another one with
+block migration status.
+
+The main json-object contains the following:
+
+- "status": migration status (json-string)
+ - Possible values: "active", "completed", "failed", "cancelled"
+- "ram": only present if "status" is "active", it is a json-object with the
+ following RAM information (in bytes):
+ - "transferred": amount transferred (json-int)
+ - "remaining": amount remaining (json-int)
+ - "total": total (json-int)
+- "disk": only present if "status" is "active" and it is a block migration,
+ it is a json-object with the following disk information (in bytes):
+ - "transferred": amount transferred (json-int)
+ - "remaining": amount remaining (json-int)
+ - "total": total (json-int)
+
+Examples:
+
+1. Before the first migration
+
+-> { "execute": "query-migrate" }
+<- { "return": {} }
+
+2. Migration is done and has succeeded
+
+-> { "execute": "query-migrate" }
+<- { "return": { "status": "completed" } }
+
+3. Migration is done and has failed
+
+-> { "execute": "query-migrate" }
+<- { "return": { "status": "failed" } }
+
+4. Migration is being performed and is not a block migration:
+
+-> { "execute": "query-migrate" }
+<- {
+ "return":{
+ "status":"active",
+ "ram":{
+ "transferred":123,
+ "remaining":123,
+ "total":246
+ }
+ }
+ }
+
+5. Migration is being performed and is a block migration:
+
+-> { "execute": "query-migrate" }
+<- {
+ "return":{
+ "status":"active",
+ "ram":{
+ "total":1057024,
+ "remaining":1053304,
+ "transferred":3720
+ },
+ "disk":{
+ "total":20971520,
+ "remaining":20880384,
+ "transferred":91136
+ }
+ }
+ }
+
+EQMP
+
+SQMP
+query-balloon
+-------------
+
+Show balloon information.
+
+Make an asynchronous request for balloon info. When the request completes a
+json-object will be returned containing the following data:
+
+- "actual": current balloon value in bytes (json-int)
+- "mem_swapped_in": Amount of memory swapped in bytes (json-int, optional)
+- "mem_swapped_out": Amount of memory swapped out in bytes (json-int, optional)
+- "major_page_faults": Number of major faults (json-int, optional)
+- "minor_page_faults": Number of minor faults (json-int, optional)
+- "free_mem": Total amount of free and unused memory in
+ bytes (json-int, optional)
+- "total_mem": Total amount of available memory in bytes (json-int, optional)
+
+Example:
+
+-> { "execute": "query-balloon" }
+<- {
+ "return":{
+ "actual":1073741824,
+ "mem_swapped_in":0,
+ "mem_swapped_out":0,
+ "major_page_faults":142,
+ "minor_page_faults":239245,
+ "free_mem":1014185984,
+ "total_mem":1044668416
+ }
+ }
+
+EQMP
+
commit 1162daa6c163ca022165a9bcb3078c2e16f32674
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Mon Sep 13 12:15:26 2010 -0300
Monitor: Convert do_info() back to HMP
This is a HMP specific handler, it makes no sense to have it
under QMP.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 7f2af49..f0854c4 100644
--- a/monitor.c
+++ b/monitor.c
@@ -636,7 +636,7 @@ static void user_async_info_handler(Monitor *mon, const mon_cmd_t *cmd)
}
}
-static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
+static void do_info(Monitor *mon, const QDict *qdict)
{
const mon_cmd_t *cmd;
const char *item = qdict_get_try_str(qdict, "item");
@@ -668,11 +668,10 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
cmd->mhandler.info(mon);
}
- return 0;
+ return;
help:
help_cmd(mon, "info");
- return 0;
}
static void do_info_version_print(Monitor *mon, const QObject *data)
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 49bcd8d..57d28ac 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -1654,8 +1654,7 @@ EQMP
.args_type = "item:s?",
.params = "[subcommand]",
.help = "show various information about the system state",
- .user_print = monitor_user_noop,
- .mhandler.cmd_new = do_info,
+ .mhandler.cmd = do_info,
},
STEXI
commit d4551293d68a1876df87400be6c71c657756d0bb
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Wed Sep 15 16:56:48 2010 -0300
Monitor: Drop is_async_return()
If I understood it correcty, the is_async_return() logic was only
used to prevent QMP from issuing duplicated success responses
for asynchronous handlers.
However, QMP doesn't use do_info() anymore so this is dead logic
and (hopefully) can be safely dropped.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 4fc0ad3..7f2af49 100644
--- a/monitor.c
+++ b/monitor.c
@@ -656,12 +656,6 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
if (monitor_handler_is_async(cmd)) {
user_async_info_handler(mon, cmd);
- /*
- * Indicate that this command is asynchronous and will not return any
- * data (not even empty). Instead, the data will be returned via a
- * completion callback.
- */
- *ret_data = qobject_from_jsonf("{ '__mon_async': 'return' }");
} else if (monitor_handler_ported(cmd)) {
QObject *info_data = NULL;
@@ -3720,15 +3714,6 @@ void monitor_set_error(Monitor *mon, QError *qerror)
}
}
-static int is_async_return(const QObject *data)
-{
- if (data && qobject_type(data) == QTYPE_QDICT) {
- return qdict_haskey(qobject_to_qdict(data), "__mon_async");
- }
-
- return 0;
-}
-
static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
{
if (monitor_ctrl_mode(mon)) {
@@ -3787,15 +3772,7 @@ static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd,
ret = cmd->mhandler.cmd_new(mon, params, &data);
handler_audit(mon, cmd, ret);
- if (is_async_return(data)) {
- /*
- * Asynchronous commands have no initial return data but they can
- * generate errors. Data is returned via the async completion handler.
- */
- if (monitor_ctrl_mode(mon) && monitor_has_error(mon)) {
- monitor_protocol_emitter(mon, NULL);
- }
- } else if (monitor_ctrl_mode(mon)) {
+ if (monitor_ctrl_mode(mon)) {
/* Monitor Protocol */
monitor_protocol_emitter(mon, data);
} else {
commit 1dcbd6f6b79d5cae4d11572ce945653ca93291cc
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Fri Sep 10 17:00:16 2010 -0300
Monitor: Drop QMP bits from do_info()
As of last commit, QMP doesn't use do_info() anymore. Simplify it.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index ff65f38..4fc0ad3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -642,7 +642,6 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
const char *item = qdict_get_try_str(qdict, "item");
if (!item) {
- assert(monitor_ctrl_mode(mon) == 0);
goto help;
}
@@ -652,24 +651,11 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
}
if (cmd->name == NULL) {
- if (monitor_ctrl_mode(mon)) {
- qerror_report(QERR_COMMAND_NOT_FOUND, item);
- return -1;
- }
goto help;
}
- if (monitor_ctrl_mode(mon) && monitor_cmd_user_only(cmd)) {
- qerror_report(QERR_COMMAND_NOT_FOUND, item);
- return -1;
- }
-
if (monitor_handler_is_async(cmd)) {
- if (monitor_ctrl_mode(mon)) {
- qmp_async_info_handler(mon, cmd);
- } else {
- user_async_info_handler(mon, cmd);
- }
+ user_async_info_handler(mon, cmd);
/*
* Indicate that this command is asynchronous and will not return any
* data (not even empty). Instead, the data will be returned via a
@@ -677,24 +663,15 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
*/
*ret_data = qobject_from_jsonf("{ '__mon_async': 'return' }");
} else if (monitor_handler_ported(cmd)) {
- cmd->mhandler.info_new(mon, ret_data);
+ QObject *info_data = NULL;
- if (!monitor_ctrl_mode(mon)) {
- /*
- * User Protocol function is called here, Monitor Protocol is
- * handled by monitor_call_handler()
- */
- if (*ret_data)
- cmd->user_print(mon, *ret_data);
+ cmd->mhandler.info_new(mon, &info_data);
+ if (info_data) {
+ cmd->user_print(mon, info_data);
+ qobject_decref(info_data);
}
} else {
- if (monitor_ctrl_mode(mon)) {
- /* handler not converted yet */
- qerror_report(QERR_COMMAND_NOT_FOUND, item);
- return -1;
- } else {
- cmd->mhandler.info(mon);
- }
+ cmd->mhandler.info(mon);
}
return 0;
commit 030db6e89d052fbf689b632d74026030bdf7a02a
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Fri Sep 10 16:03:38 2010 -0300
QMP: Don't use do_info()
Since its inception, QMP has been using HMP's do_info() function
to run query commands.
This was a bad choice, as it made do_info() more complex and
contributed to couple QMP and HMP.
This commit fixes that by doing the following changes:
1. Introduce qmp_find_query_cmd() and use it to directly lookup
the info_cmds table
2. Introduce qmp_call_query_cmd() so that QMP code is able
to call query handlers without using do_info()
3. Drop do_info() usage (via monitor_find_command("info"))
We need all the three changes in one shot so that we don't break
the calling of query commands in QMP.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index 2efff8a..ff65f38 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3390,6 +3390,11 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname)
return search_dispatch_table(mon_cmds, cmdname);
}
+static const mon_cmd_t *qmp_find_query_cmd(const char *info_item)
+{
+ return search_dispatch_table(info_cmds, info_item);
+}
+
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
const char *cmdline,
QDict *qdict)
@@ -4329,6 +4334,24 @@ static QDict *qmp_check_input_obj(QObject *input_obj)
return input_dict;
}
+static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd)
+{
+ QObject *ret_data = NULL;
+
+ if (monitor_handler_is_async(cmd)) {
+ qmp_async_info_handler(mon, cmd);
+ if (monitor_has_error(mon)) {
+ monitor_protocol_emitter(mon, NULL);
+ }
+ } else {
+ cmd->mhandler.info_new(mon, &ret_data);
+ if (ret_data) {
+ monitor_protocol_emitter(mon, ret_data);
+ qobject_decref(ret_data);
+ }
+ }
+}
+
static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
{
int err;
@@ -4336,8 +4359,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
QDict *input, *args;
const mon_cmd_t *cmd;
Monitor *mon = cur_mon;
- const char *cmd_name, *info_item;
+ const char *cmd_name, *query_cmd;
+ query_cmd = NULL;
args = input = NULL;
obj = json_parser_parse(tokens, NULL);
@@ -4363,16 +4387,13 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
}
/*
- * XXX: We need this special case until we get info handlers
- * converted into 'query-' commands
+ * XXX: We need this special case until QMP has its own dispatch table
*/
if (compare_cmd(cmd_name, "info")) {
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_out;
- } else if (strstart(cmd_name, "query-", &info_item)) {
- cmd = monitor_find_command("info");
- qdict_put_obj(input, "arguments",
- qobject_from_jsonf("{ 'item': %s }", info_item));
+ } else if (strstart(cmd_name, "query-", &query_cmd)) {
+ cmd = qmp_find_query_cmd(query_cmd);
} else {
cmd = monitor_find_command(cmd_name);
}
@@ -4395,7 +4416,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
- if (monitor_handler_is_async(cmd)) {
+ if (query_cmd) {
+ qmp_call_query_cmd(mon, cmd);
+ } else if (monitor_handler_is_async(cmd)) {
err = qmp_async_cmd_handler(mon, cmd, args);
if (err) {
/* emit the error response */
commit 0fb88582e60e16e809c1aabc2c4b3e1f0832e267
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Wed Sep 15 10:56:17 2010 -0300
QMP: handle_qmp_command(): Move 'cmd' sanity check
Next commit will change how query commands are handled in a
way that the 'cmd' sanity check is also going to be needed
for query commands handling.
Let's move it out of the else body then.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index da76eab..2efff8a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4375,11 +4375,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
qobject_from_jsonf("{ 'item': %s }", info_item));
} else {
cmd = monitor_find_command(cmd_name);
- if (!cmd || !monitor_handler_ported(cmd)
- || monitor_cmd_user_only(cmd)) {
- qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
- goto err_out;
- }
+ }
+
+ if (!cmd || !monitor_handler_ported(cmd) || monitor_cmd_user_only(cmd)) {
+ qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
+ goto err_out;
}
obj = qdict_get(input, "arguments");
commit 945c5ac8d3c792bab36dc0990f11ca55f6eb3148
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date: Mon Sep 13 13:17:58 2010 -0300
Monitor: Introduce search_dispatch_table()
It's a generic version of monitor_find_command() which searches
the dispatch table passed as an argument.
Future commits will introduce new dispatch tables, so we need
common code to search them.
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index a33cdc2..da76eab 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3371,11 +3371,12 @@ static int is_valid_option(const char *c, const char *typestr)
return (typestr != NULL);
}
-static const mon_cmd_t *monitor_find_command(const char *cmdname)
+static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
+ const char *cmdname)
{
const mon_cmd_t *cmd;
- for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
+ for (cmd = disp_table; cmd->name != NULL; cmd++) {
if (compare_cmd(cmdname, cmd->name)) {
return cmd;
}
@@ -3384,6 +3385,11 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname)
return NULL;
}
+static const mon_cmd_t *monitor_find_command(const char *cmdname)
+{
+ return search_dispatch_table(mon_cmds, cmdname);
+}
+
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
const char *cmdline,
QDict *qdict)
commit 07b0403dfc2b2ac179ae5b48105096cc2d03375a
Author: Eduardo Habkost <ehabkost at redhat.com>
Date: Tue Sep 14 13:43:39 2010 -0300
disable guest-provided stats on "info balloon" command
The addition of memory stats reporting to the virtio balloon causes
the 'info balloon' command to become asynchronous. This is a regression
because in some cases it can hang the user monitor.
This is an alternative to Adam Litke's patch. Adam's patch disabled the
corresponding (guest-visible) virtio feature bit, causing issues for migration.
Original discussion is available at:
http://marc.info/?l=qemu-devel&m=128448124328314&w=2
Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
Acked-by: Adam Litke <agl at us.ibm.com
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 1e74674..8adddea 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -29,6 +29,10 @@
#include <sys/mman.h>
#endif
+/* Disable guest-provided stats by now (https://bugzilla.redhat.com/show_bug.cgi?id=623903) */
+#define ENABLE_GUEST_STATS 0
+
+
typedef struct VirtIOBalloon
{
VirtIODevice vdev;
@@ -83,12 +87,14 @@ static QObject *get_stats_qobject(VirtIOBalloon *dev)
VIRTIO_BALLOON_PFN_SHIFT);
stat_put(dict, "actual", actual);
+#if ENABLE_GUEST_STATS
stat_put(dict, "mem_swapped_in", dev->stats[VIRTIO_BALLOON_S_SWAP_IN]);
stat_put(dict, "mem_swapped_out", dev->stats[VIRTIO_BALLOON_S_SWAP_OUT]);
stat_put(dict, "major_page_faults", dev->stats[VIRTIO_BALLOON_S_MAJFLT]);
stat_put(dict, "minor_page_faults", dev->stats[VIRTIO_BALLOON_S_MINFLT]);
stat_put(dict, "free_mem", dev->stats[VIRTIO_BALLOON_S_MEMFREE]);
stat_put(dict, "total_mem", dev->stats[VIRTIO_BALLOON_S_MEMTOT]);
+#endif
return QOBJECT(dict);
}
@@ -214,7 +220,7 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target,
}
dev->stats_callback = cb;
dev->stats_opaque_callback_data = cb_data;
- if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) {
+ if (ENABLE_GUEST_STATS && (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ))) {
virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset);
virtio_notify(&dev->vdev, dev->svq);
} else {
commit 39eaab9ac2a82f5370758e8aeb8b7196f34fdabf
Author: Daniel P. Berrange <berrange at redhat.com>
Date: Mon Jun 7 15:42:31 2010 +0100
Add option to turn on JSON pretty printing in monitor
Expaned '-mon' arg to allow a 'pretty=on' flag. This makes the
monitor pretty print its replies to easy human debugging / reading
Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/monitor.c b/monitor.c
index e602480..a33cdc2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -351,7 +351,10 @@ static void monitor_json_emitter(Monitor *mon, const QObject *data)
{
QString *json;
- json = qobject_to_json(data);
+ if (mon->flags & MONITOR_USE_PRETTY)
+ json = qobject_to_json_pretty(data);
+ else
+ json = qobject_to_json(data);
assert(json != NULL);
qstring_append_chr(json, '\n');
diff --git a/monitor.h b/monitor.h
index 38b22a4..f2122b5 100644
--- a/monitor.h
+++ b/monitor.h
@@ -14,6 +14,7 @@ extern Monitor *default_mon;
#define MONITOR_IS_DEFAULT 0x01
#define MONITOR_USE_READLINE 0x02
#define MONITOR_USE_CONTROL 0x04
+#define MONITOR_USE_PRETTY 0x08
/* flags for monitor commands */
#define MONITOR_CMD_ASYNC 0x0001
diff --git a/qemu-config.c b/qemu-config.c
index e3b746c..6052a28 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -283,6 +283,9 @@ static QemuOptsList qemu_mon_opts = {
},{
.name = "default",
.type = QEMU_OPT_BOOL,
+ },{
+ .name = "pretty",
+ .type = QEMU_OPT_BOOL,
},
{ /* end of list */ }
},
diff --git a/vl.c b/vl.c
index d352d18..939ee87 100644
--- a/vl.c
+++ b/vl.c
@@ -1562,6 +1562,9 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
exit(1);
}
+ if (qemu_opt_get_bool(opts, "pretty", 0))
+ flags |= MONITOR_USE_PRETTY;
+
if (qemu_opt_get_bool(opts, "default", 0))
flags |= MONITOR_IS_DEFAULT;
commit 212b6008686369b288a2b71e4f1b25f07d854763
Author: Daniel P. Berrange <berrange at redhat.com>
Date: Mon Jun 7 15:42:14 2010 +0100
Add support for JSON pretty printing
The monitor does not pretty-print JSON output, so that everything
will be on a single line reply. When JSON docs get large this is
quite unpleasant to read. For the future command line capabilities
query ability, huge JSON docs will be available. This needs the
ability to pretty-print.
This introduces a new API qobject_to_json_pretty() that does
a minimal indentation of list and dict members. As an example,
this makes
{"QMP": {"version": {"micro": 50, "minor": 12, "package": "", "major": 0}, "capabilities": []}}
Output as
{
"QMP": {
"version": {
"micro": 50,
"minor": 12,
"package": "",
"major": 0
},
"capabilities": [
]
}
}
NB: this is not turned on for the QMP monitor.
Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
diff --git a/qjson.c b/qjson.c
index e4ee433..f9c8e77 100644
--- a/qjson.c
+++ b/qjson.c
@@ -72,43 +72,57 @@ QObject *qobject_from_jsonf(const char *string, ...)
typedef struct ToJsonIterState
{
+ int indent;
+ int pretty;
int count;
QString *str;
} ToJsonIterState;
-static void to_json(const QObject *obj, QString *str);
+static void to_json(const QObject *obj, QString *str, int pretty, int indent);
static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
{
ToJsonIterState *s = opaque;
QString *qkey;
+ int j;
- if (s->count) {
+ if (s->count)
qstring_append(s->str, ", ");
+
+ if (s->pretty) {
+ qstring_append(s->str, "\n");
+ for (j = 0 ; j < s->indent ; j++)
+ qstring_append(s->str, " ");
}
qkey = qstring_from_str(key);
- to_json(QOBJECT(qkey), s->str);
+ to_json(QOBJECT(qkey), s->str, s->pretty, s->indent);
QDECREF(qkey);
qstring_append(s->str, ": ");
- to_json(obj, s->str);
+ to_json(obj, s->str, s->pretty, s->indent);
s->count++;
}
static void to_json_list_iter(QObject *obj, void *opaque)
{
ToJsonIterState *s = opaque;
+ int j;
- if (s->count) {
+ if (s->count)
qstring_append(s->str, ", ");
+
+ if (s->pretty) {
+ qstring_append(s->str, "\n");
+ for (j = 0 ; j < s->indent ; j++)
+ qstring_append(s->str, " ");
}
- to_json(obj, s->str);
+ to_json(obj, s->str, s->pretty, s->indent);
s->count++;
}
-static void to_json(const QObject *obj, QString *str)
+static void to_json(const QObject *obj, QString *str, int pretty, int indent)
{
switch (qobject_type(obj)) {
case QTYPE_QINT: {
@@ -193,8 +207,16 @@ static void to_json(const QObject *obj, QString *str)
s.count = 0;
s.str = str;
+ s.indent = indent + 1;
+ s.pretty = pretty;
qstring_append(str, "{");
qdict_iter(val, to_json_dict_iter, &s);
+ if (pretty) {
+ int j;
+ qstring_append(str, "\n");
+ for (j = 0 ; j < indent ; j++)
+ qstring_append(str, " ");
+ }
qstring_append(str, "}");
break;
}
@@ -204,8 +226,16 @@ static void to_json(const QObject *obj, QString *str)
s.count = 0;
s.str = str;
+ s.indent = indent + 1;
+ s.pretty = pretty;
qstring_append(str, "[");
qlist_iter(val, (void *)to_json_list_iter, &s);
+ if (pretty) {
+ int j;
+ qstring_append(str, "\n");
+ for (j = 0 ; j < indent ; j++)
+ qstring_append(str, " ");
+ }
qstring_append(str, "]");
break;
}
@@ -249,7 +279,16 @@ QString *qobject_to_json(const QObject *obj)
{
QString *str = qstring_new();
- to_json(obj, str);
+ to_json(obj, str, 0, 0);
+
+ return str;
+}
+
+QString *qobject_to_json_pretty(const QObject *obj)
+{
+ QString *str = qstring_new();
+
+ to_json(obj, str, 1, 0);
return str;
}
diff --git a/qjson.h b/qjson.h
index 7afec2e..cd60e0b 100644
--- a/qjson.h
+++ b/qjson.h
@@ -24,5 +24,6 @@ QObject *qobject_from_jsonf(const char *string, ...)
QObject *qobject_from_jsonv(const char *string, va_list *ap);
QString *qobject_to_json(const QObject *obj);
+QString *qobject_to_json_pretty(const QObject *obj);
#endif /* QJSON_H */
commit 2c50e26efdb7e405ecacf89e6a57a60179226dd8
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date: Wed Sep 29 15:31:44 2010 +0200
powerpc: Add a virtex5 ml507 refdesign board
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/Makefile.target b/Makefile.target
index a4e80b1..91d0381 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -217,9 +217,17 @@ obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
obj-ppc-y += ppc440.o ppc440_bamboo.o
# PowerPC E500 boards
obj-ppc-y += ppce500_mpc8544ds.o
+# PowerPC 440 Xilinx ML507 reference board.
+obj-ppc-y += virtex_ml507.o
obj-ppc-$(CONFIG_KVM) += kvm_ppc.o
obj-ppc-$(CONFIG_FDT) += device_tree.o
+# Xilinx PPC peripherals
+obj-ppc-y += xilinx_intc.o
+obj-ppc-y += xilinx_timer.o
+obj-ppc-y += xilinx_uartlite.o
+obj-ppc-y += xilinx_ethlite.o
+
obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
obj-mips-y += mips_addr.o mips_timer.o mips_int.o
obj-mips-y += vga.o i8259.o
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index c026bbb..940f4bf 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -32,4 +32,6 @@ CONFIG_IDE_MACIO=y
CONFIG_NE2000_ISA=y
CONFIG_SOUND=y
CONFIG_VIRTIO_PCI=y
+CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y
+CONFIG_PTIMER=y
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index 0101a28..e1bc6b8 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -32,4 +32,6 @@ CONFIG_IDE_MACIO=y
CONFIG_NE2000_ISA=y
CONFIG_SOUND=y
CONFIG_VIRTIO_PCI=y
+CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y
+CONFIG_PTIMER=y
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index 8ba9ac1..8f1cc09 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -32,4 +32,6 @@ CONFIG_IDE_MACIO=y
CONFIG_NE2000_ISA=y
CONFIG_SOUND=y
CONFIG_VIRTIO_PCI=y
+CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y
+CONFIG_PTIMER=y
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
new file mode 100644
index 0000000..2af3b81
--- /dev/null
+++ b/hw/virtex_ml507.c
@@ -0,0 +1,278 @@
+/*
+ * Model of Xilinx Virtex5 ML507 PPC-440 refdesign.
+ *
+ * Copyright (c) 2010 Edgar E. Iglesias.
+ *
+ * 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.
+ */
+
+#include "sysbus.h"
+#include "hw.h"
+#include "pc.h"
+#include "net.h"
+#include "flash.h"
+#include "sysemu.h"
+#include "devices.h"
+#include "boards.h"
+#include "device_tree.h"
+#include "loader.h"
+#include "elf.h"
+#include "qemu-log.h"
+
+#include "ppc.h"
+#include "ppc4xx.h"
+#include "ppc440.h"
+#include "ppc405.h"
+
+#include "blockdev.h"
+#include "xilinx.h"
+
+#define EPAPR_MAGIC (0x45504150)
+#define FLASH_SIZE (16 * 1024 * 1024)
+
+static struct boot_info
+{
+ uint32_t bootstrap_pc;
+ uint32_t cmdline;
+ uint32_t fdt;
+ uint32_t ima_size;
+ void *vfdt;
+} boot_info;
+
+/* Create reset TLB entries for BookE, spanning the 32bit addr space. */
+static void mmubooke_create_initial_mapping(CPUState *env,
+ target_ulong va,
+ target_phys_addr_t pa)
+{
+ ppcemb_tlb_t *tlb = &env->tlb[0].tlbe;
+
+ tlb->attr = 0;
+ tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
+ tlb->size = 1 << 31; /* up to 0x80000000 */
+ tlb->EPN = va & TARGET_PAGE_MASK;
+ tlb->RPN = pa & TARGET_PAGE_MASK;
+ tlb->PID = 0;
+
+ tlb = &env->tlb[1].tlbe;
+ tlb->attr = 0;
+ tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
+ tlb->size = 1 << 31; /* up to 0xffffffff */
+ tlb->EPN = 0x80000000 & TARGET_PAGE_MASK;
+ tlb->RPN = 0x80000000 & TARGET_PAGE_MASK;
+ tlb->PID = 0;
+}
+
+static CPUState *ppc440_init_xilinx(ram_addr_t *ram_size,
+ int do_init,
+ const char *cpu_model,
+ clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
+ uint32_t sysclk)
+{
+ CPUState *env;
+ qemu_irq *pic;
+ qemu_irq *irqs;
+
+ env = cpu_init(cpu_model);
+ if (!env) {
+ fprintf(stderr, "Unable to initialize CPU!\n");
+ exit(1);
+ }
+
+ cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
+ cpu_clk->opaque = env;
+ /* Set time-base frequency to sysclk */
+ tb_clk->cb = ppc_emb_timers_init(env, sysclk, PPC_INTERRUPT_DECR);
+ tb_clk->opaque = env;
+
+ ppc_dcr_init(env, NULL, NULL);
+
+ /* interrupt controller */
+ irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
+ irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
+ irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
+ pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
+ return env;
+}
+
+static void main_cpu_reset(void *opaque)
+{
+ CPUState *env = opaque;
+ struct boot_info *bi = env->load_info;
+
+ cpu_reset(env);
+ /* Linux Kernel Parameters (passing device tree):
+ * r3: pointer to the fdt
+ * r4: 0
+ * r5: 0
+ * r6: epapr magic
+ * r7: size of IMA in bytes
+ * r8: 0
+ * r9: 0
+ */
+ env->gpr[1] = (16<<20) - 8;
+ /* Provide a device-tree. */
+ env->gpr[3] = bi->fdt;
+ env->nip = bi->bootstrap_pc;
+
+ /* Create a mapping for the kernel. */
+ mmubooke_create_initial_mapping(env, 0, 0);
+ env->gpr[6] = tswap32(EPAPR_MAGIC);
+ env->gpr[7] = bi->ima_size;
+}
+
+#define BINARY_DEVICE_TREE_FILE "virtex-ml507.dtb"
+static int xilinx_load_device_tree(target_phys_addr_t addr,
+ uint32_t ramsize,
+ target_phys_addr_t initrd_base,
+ target_phys_addr_t initrd_size,
+ const char *kernel_cmdline)
+{
+ char *path;
+ int fdt_size;
+#ifdef CONFIG_FDT
+ void *fdt;
+ int r;
+
+ /* Try the local "ppc.dtb" override. */
+ fdt = load_device_tree("ppc.dtb", &fdt_size);
+ if (!fdt) {
+ path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
+ if (path) {
+ fdt = load_device_tree(path, &fdt_size);
+ qemu_free(path);
+ }
+ if (!fdt)
+ return 0;
+ }
+
+ r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
+ if (r < 0)
+ fprintf(stderr, "couldn't set /chosen/bootargs\n");
+ cpu_physical_memory_write (addr, (void *)fdt, fdt_size);
+#else
+ /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
+ to the kernel. */
+ fdt_size = load_image_targphys("ppc.dtb", addr, 0x10000);
+ if (fdt_size < 0) {
+ path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
+ if (path) {
+ fdt_size = load_image_targphys(path, addr, 0x10000);
+ qemu_free(path);
+ }
+ }
+
+ if (kernel_cmdline) {
+ fprintf(stderr,
+ "Warning: missing libfdt, cannot pass cmdline to kernel!\n");
+ }
+#endif
+ return fdt_size;
+}
+
+static void virtex_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+ DeviceState *dev;
+ CPUState *env;
+ target_phys_addr_t ram_base = 0;
+ DriveInfo *dinfo;
+ ram_addr_t phys_ram;
+ ram_addr_t phys_flash;
+ qemu_irq irq[32], *cpu_irq;
+ clk_setup_t clk_setup[7];
+ int kernel_size;
+ int i;
+
+ /* init CPUs */
+ if (cpu_model == NULL) {
+ cpu_model = "440-Xilinx";
+ }
+
+ memset(clk_setup, 0, sizeof(clk_setup));
+ env = ppc440_init_xilinx(&ram_size, 1, cpu_model, &clk_setup[0],
+ &clk_setup[1], 400000000);
+ qemu_register_reset(main_cpu_reset, env);
+
+ phys_ram = qemu_ram_alloc(NULL, "ram", ram_size);
+ cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
+
+ phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
+ pflash_cfi01_register(0xfc000000, phys_flash,
+ dinfo ? dinfo->bdrv : NULL, (64 * 1024),
+ FLASH_SIZE >> 16,
+ 1, 0x89, 0x18, 0x0000, 0x0, 1);
+
+ cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
+ dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0);
+ for (i = 0; i < 32; i++) {
+ irq[i] = qdev_get_gpio_in(dev, i);
+ }
+
+ serial_mm_init(0x83e01003ULL, 2, irq[9], 115200, serial_hds[0], 1, 0);
+
+ /* 2 timers at irq 2 @ 62 Mhz. */
+ xilinx_timer_create(0x83c00000, irq[3], 2, 62 * 1000000);
+
+ if (kernel_filename) {
+ uint64_t entry, low, high;
+ uint32_t base32;
+ target_phys_addr_t boot_offset;
+
+ /* Boots a kernel elf binary. */
+ kernel_size = load_elf(kernel_filename, NULL, NULL,
+ &entry, &low, &high, 1, ELF_MACHINE, 0);
+ base32 = entry;
+ boot_info.bootstrap_pc = entry & 0x00ffffff;
+
+ if (kernel_size < 0) {
+ boot_offset = 0x1200000;
+ /* If we failed loading ELF's try a raw image. */
+ kernel_size = load_image_targphys(kernel_filename,
+ boot_offset,
+ ram_size);
+ boot_info.bootstrap_pc = boot_offset;
+ high = boot_info.bootstrap_pc + kernel_size + 8192;
+ }
+
+ boot_info.ima_size = kernel_size;
+
+ /* Provide a device-tree. */
+ boot_info.fdt = high + (8192 * 2);
+ boot_info.fdt &= ~8191;
+ xilinx_load_device_tree(boot_info.fdt, ram_size, 0, 0, kernel_cmdline);
+ }
+ env->load_info = &boot_info;
+}
+
+static QEMUMachine virtex_machine = {
+ .name = "virtex-ml507",
+ .desc = "Xilinx Virtex ML507 reference design",
+ .init = virtex_init,
+};
+
+static void virtex_machine_init(void)
+{
+ qemu_register_machine(&virtex_machine);
+}
+
+machine_init(virtex_machine_init);
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index dc1f4b8..bf81941 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -702,6 +702,10 @@ struct CPUPPCState {
/* temporary hack to handle OSI calls (only used if non NULL) */
int (*osi_call)(struct CPUPPCState *env);
+
+#if !defined(CONFIG_USER_ONLY)
+ void *load_info; /* Holds boot loading state. */
+#endif
};
#if !defined(CONFIG_USER_ONLY)
commit 95070372f7477f44add9af9b55970ae1b92c3100
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date: Sat Sep 11 15:29:01 2010 +0200
powerpc: Add a ppc-440x5 Xilinx model
Add a powerpc 440x5 with the model ID on the Xilinx virtex5.
Connect the 440x5 to the 40x interrupt logic.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Signed-off-by: Alexander Graf <agraf at suse.de>
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 2bd8b00..05ffe95 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -3596,7 +3596,6 @@ static void init_proc_440x4 (CPUPPCState *env)
POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
#define check_pow_440x5 check_pow_nocheck
-__attribute__ (( unused ))
static void init_proc_440x5 (CPUPPCState *env)
{
/* Time base */
@@ -3656,7 +3655,7 @@ static void init_proc_440x5 (CPUPPCState *env)
init_excp_BookE(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
+ ppc40x_irq_init(env);
}
/* PowerPC 460 (guessed) */
@@ -6536,6 +6535,7 @@ enum {
#if 0
CPU_POWERPC_440A4 = xxx,
#endif
+ CPU_POWERPC_440_XILINX = 0x7ff21910,
#if 0
CPU_POWERPC_440A5 = xxx,
#endif
@@ -7464,6 +7464,8 @@ static const ppc_def_t ppc_defs[] = {
/* PowerPC 440 A4 */
POWERPC_DEF("440A4", CPU_POWERPC_440A4, 440x4),
#endif
+ /* PowerPC 440 Xilinx 5 */
+ POWERPC_DEF("440-Xilinx", CPU_POWERPC_440_XILINX, 440x5),
#if defined (TODO)
/* PowerPC 440 A5 */
POWERPC_DEF("440A5", CPU_POWERPC_440A5, 440x5),
commit 5251d6add68f343d7e47b5ef0e44694e98605503
Author: Andreas Färber <andreas.faerber at web.de>
Date: Tue Sep 28 23:48:42 2010 +0200
tap: Remove double include of util.h
If neither of __FreeBSD__, __FreeBSD_kernel__ and __DragonFly__ is defined,
util.h is included from tap-bsd.c.
Don't include it again if __OpenBSD__ is defined.
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 3513075..efccfe0 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -37,10 +37,6 @@
#include <util.h>
#endif
-#if defined(__OpenBSD__)
-#include <util.h>
-#endif
-
int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required)
{
int fd;
commit fd5723b385557bc77b93dfe5ab591813407686c0
Author: Wu Fengguang <fengguang.wu at intel.com>
Date: Wed Sep 29 12:18:41 2010 +0800
pulse-audio: fix bug on updating rpos
Fix a rpos coordination bug between qpa_run_out() and qpa_thread_out(),
which shows up as playback noises.
qpa_run_out()
qpa_thread_out loop N critical section 1
qpa_run_out() qpa_thread_out loop N doing pa_simple_write()
qpa_run_out() qpa_thread_out loop N doing pa_simple_write()
qpa_thread_out loop N critical section 2
qpa_thread_out loop N+1 critical section 1
qpa_run_out() qpa_thread_out loop N+1 doing pa_simple_write()
In the above scheme, "qpa_thread_out loop N+1 critical section 1" will
get the same rpos as the one used by "qpa_thread_out loop N critical
section 1". So it will be reading dead samples from the old rpos.
The rpos can only be updated back to qpa_thread_out when there is a
qpa_run_out() run between two qpa_thread_out loops.
normal sequence:
qpa_thread_out:
hw->rpos (X0) => local rpos => pa->rpos (X1)
qpa_run_out:
pa->rpos (X1) => hw->rpos (X1)
qpa_thread_out:
hw->rpos (X1) => local rpos => pa->rpos (X2)
buggy sequence:
qpa_thread_out:
hw->rpos (X0) => local rpos => pa->rpos (X1)
qpa_thread_out:
hw->rpos (X0) => local rpos => pa->rpos (X1')
Obviously qpa_run_out() shall be called at least once between any two
qpa_thread_out loops (after pa->rpos is set), in order for the new
qpa_thread_out loop to see the updated rpos.
Setting pa->live to 0 does the trick. The next loop will have to wait
for one qpa_run_out() invocation in order to get a non-zero pa->live
and proceed.
Signed-off-by: malc <av1474 at comtv.ru>
Signed-off-by: Wu Fengguang <fengguang.wu at intel.com>
diff --git a/audio/paaudio.c b/audio/paaudio.c
index 9118ece..ff71dac 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -110,8 +110,8 @@ static void *qpa_thread_out (void *arg)
return NULL;
}
+ pa->live = 0;
pa->rpos = rpos;
- pa->live -= decr;
pa->decr += decr;
}
commit 575c153f4f5cc23442e194619874de8ad4e6dd9c
Author: malc <av1474 at comtv.ru>
Date: Tue Sep 28 08:54:24 2010 +0400
audio: Fix memory size for resampling buffer in DAC case
Signed-off-by: malc <av1474 at comtv.ru>
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 2f5224b..fd4469e 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -108,11 +108,7 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
{
int samples;
-#ifdef DAC
- samples = sw->hw->samples;
-#else
samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
-#endif
sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (struct st_sample));
if (!sw->buf) {
commit 9fe6de944930985885510f8e95d14104437d7c32
Author: Blue Swirl <blauwirbel at gmail.com>
Date: Sun Sep 26 16:07:57 2010 +0000
mingw: add version information to the executables
Add QEMU version information to the executables, based on earlier
work by C. W. Betts and Robert Riebisch.
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/Makefile b/Makefile
index 090d632..fca1e7a 100644
--- a/Makefile
+++ b/Makefile
@@ -114,16 +114,20 @@ trace.o: trace.c $(GENERATED_HEADERS)
simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
+version.o: $(SRC_PATH)/version.rc config-host.mak
+ $(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@")
+
+version-obj-$(CONFIG_WIN32) += version.o
######################################################################
qemu-img.o: qemu-img-cmds.h
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
-qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y)
+qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
-qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y)
+qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
-qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y)
+qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@")
diff --git a/Makefile.objs b/Makefile.objs
index dad4593..dde3ba9 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -86,6 +86,7 @@ common-obj-y += block-migration.o
common-obj-$(CONFIG_BRLAPI) += baum.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
+common-obj-$(CONFIG_WIN32) += version.o
audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
audio-obj-$(CONFIG_SDL) += sdlaudio.o
diff --git a/configure b/configure
index 02bda64..8fe4bbe 100755
--- a/configure
+++ b/configure
@@ -83,6 +83,7 @@ install="install"
objcopy="objcopy"
ld="ld"
strip="strip"
+windres="windres"
helper_cflags=""
libs_softmmu=""
libs_tools=""
@@ -129,6 +130,7 @@ ar="${cross_prefix}${ar}"
objcopy="${cross_prefix}${objcopy}"
ld="${cross_prefix}${ld}"
strip="${cross_prefix}${strip}"
+windres="${cross_prefix}${windres}"
# default flags for all hosts
QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
@@ -2319,6 +2321,15 @@ fi
echo "HOST_LONG_BITS=$hostlongbits" >> $config_host_mak
if test "$mingw32" = "yes" ; then
echo "CONFIG_WIN32=y" >> $config_host_mak
+ rc_version=`cat $source_path/VERSION`
+ version_major=${rc_version%%.*}
+ rc_version=${rc_version#*.}
+ version_minor=${rc_version%%.*}
+ rc_version=${rc_version#*.}
+ version_subminor=${rc_version%%.*}
+ version_micro=0
+ echo "CONFIG_FILEVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak
+ echo "CONFIG_PRODUCTVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak
else
echo "CONFIG_POSIX=y" >> $config_host_mak
fi
@@ -2565,6 +2576,7 @@ fi
echo "AR=$ar" >> $config_host_mak
echo "OBJCOPY=$objcopy" >> $config_host_mak
echo "LD=$ld" >> $config_host_mak
+echo "WINDRES=$windres" >> $config_host_mak
echo "CFLAGS=$CFLAGS" >> $config_host_mak
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
echo "HELPER_CFLAGS=$helper_cflags" >> $config_host_mak
diff --git a/version.rc b/version.rc
new file mode 100644
index 0000000..82e10ec
--- /dev/null
+++ b/version.rc
@@ -0,0 +1,28 @@
+#include <winver.h>
+#include "config-host.h"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION CONFIG_FILEVERSION
+PRODUCTVERSION CONFIG_PRODUCTVERSION
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+FILESUBTYPE VFT2_UNKNOWN
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904E4"
+ {
+ VALUE "CompanyName", "http://www.qemu.org"
+ VALUE "FileDescription", "QEMU machine emulators and tools"
+ VALUE "FileVersion", QEMU_VERSION
+ VALUE "LegalCopyright", "Copyright various authors. Released under the GNU General Public License."
+ VALUE "LegalTrademarks", "QEMU is a trademark of Fabrice Bellard."
+ VALUE "ProductName", "QEMU"
+ }
+ }
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 1252
+ }
+}
commit 0ba8681eee36af77109505c34b5e29da52fa51ba
Author: Loïc Minier <loic.minier at linaro.org>
Date: Sat Sep 25 21:52:30 2010 +0200
Avoid exit in trap as it breaks with some shells
Don't call exit in the trap handler as it causes the return code to be
zero with some buggy shells (dash and pdksh at least) and is useless
here anyway.
Signed-off-by: Loïc Minier <loic.minier at linaro.org>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/configure b/configure
index 6a21bf2..02bda64 100755
--- a/configure
+++ b/configure
@@ -15,7 +15,9 @@ TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c"
TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
-trap "rm -f $TMPC $TMPO $TMPE ; exit" EXIT INT QUIT TERM
+# NB: do not call "exit" in the trap handler; this is buggy with some shells;
+# see <1285349658-3122-1-git-send-email-loic.minier at linaro.org>
+trap "rm -f $TMPC $TMPO $TMPE" EXIT INT QUIT TERM
compile_object() {
$cc $QEMU_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null
commit e78815a554adaa551d62a71be10ee2fcf128e473
Author: Andreas Färber <afaerber at opensolaris.org>
Date: Sat Sep 25 11:26:05 2010 +0000
Introduce qemu_madvise()
vl.c has a Sun-specific hack to supply a prototype for madvise(),
but the call site has apparently moved to arch_init.c.
Haiku doesn't implement madvise() in favor of posix_madvise().
OpenBSD and Solaris 10 don't implement posix_madvise() but madvise().
MinGW implements neither.
Check for madvise() and posix_madvise() in configure and supply qemu_madvise()
as wrapper. Prefer madvise() over posix_madvise() due to flag availability.
Convert all callers to use qemu_madvise() and QEMU_MADV_*.
Note that on Solaris the warning is fixed by moving the madvise() prototype,
not by qemu_madvise() itself. It helps with porting though, and it simplifies
most call sites.
v7 -> v8:
* Some versions of MinGW have no sys/mman.h header. Reported by Blue Swirl.
v6 -> v7:
* Adopt madvise() rather than posix_madvise() semantics for returning errors.
* Use EINVAL in place of ENOTSUP.
v5 -> v6:
* Replace two leftover instances of POSIX_MADV_NORMAL with QEMU_MADV_INVALID.
Spotted by Blue Swirl.
v4 -> v5:
* Introduce QEMU_MADV_INVALID, suggested by Alexander Graf.
Note that this relies on -1 not being a valid advice value.
v3 -> v4:
* Eliminate #ifdefs at qemu_advise() call sites. Requested by Blue Swirl.
This will currently break the check in kvm-all.c by calling madvise() with
a supported flag, which will not fail. Ideas/patches welcome.
v2 -> v3:
* Reuse the *_MADV_* defines for QEMU_MADV_*. Suggested by Alexander Graf.
* Add configure check for madvise(), too.
Add defines to Makefile, not QEMU_CFLAGS.
Convert all callers, untested. Suggested by Blue Swirl.
* Keep Solaris' madvise() prototype around. Pointed out by Alexander Graf.
* Display configure check results.
v1 -> v2:
* Don't rely on posix_madvise() availability, add qemu_madvise().
Suggested by Blue Swirl.
Signed-off-by: Andreas Färber <afaerber at opensolaris.org>
Cc: Blue Swirl <blauwirbel at gmail.com>
Cc: Alexander Graf <agraf at suse.de>
Cc: Andrea Arcangeli <aarcange at redhat.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/arch_init.c b/arch_init.c
index e468c0c..a910033 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -396,7 +396,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
#ifndef _WIN32
if (ch == 0 &&
(!kvm_enabled() || kvm_has_sync_mmu())) {
- madvise(host, TARGET_PAGE_SIZE, MADV_DONTNEED);
+ qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
}
#endif
} else if (flags & RAM_SAVE_FLAG_PAGE) {
diff --git a/configure b/configure
index 3bfc5e9..6a21bf2 100755
--- a/configure
+++ b/configure
@@ -2072,6 +2072,31 @@ if compile_prog "" "" ; then
fi
##########################################
+# check if we have madvise
+
+madvise=no
+cat > $TMPC << EOF
+#include <sys/types.h>
+#include <sys/mman.h>
+int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }
+EOF
+if compile_prog "" "" ; then
+ madvise=yes
+fi
+
+##########################################
+# check if we have posix_madvise
+
+posix_madvise=no
+cat > $TMPC << EOF
+#include <sys/mman.h>
+int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }
+EOF
+if compile_prog "" "" ; then
+ posix_madvise=yes
+fi
+
+##########################################
# check if trace backend exists
sh "$source_path/tracetool" "--$trace_backend" --check-backend > /dev/null 2> /dev/null
@@ -2238,6 +2263,8 @@ echo "KVM support $kvm"
echo "fdt support $fdt"
echo "preadv support $preadv"
echo "fdatasync $fdatasync"
+echo "madvise $madvise"
+echo "posix_madvise $posix_madvise"
echo "uuid support $uuid"
echo "vhost-net support $vhost_net"
echo "Trace backend $trace_backend"
@@ -2478,6 +2505,12 @@ fi
if test "$fdatasync" = "yes" ; then
echo "CONFIG_FDATASYNC=y" >> $config_host_mak
fi
+if test "$madvise" = "yes" ; then
+ echo "CONFIG_MADVISE=y" >> $config_host_mak
+fi
+if test "$posix_madvise" = "yes" ; then
+ echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak
+fi
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
diff --git a/exec.c b/exec.c
index 380dab5..9b5464f 100644
--- a/exec.c
+++ b/exec.c
@@ -2841,9 +2841,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
new_block->host = file_ram_alloc(new_block, size, mem_path);
if (!new_block->host) {
new_block->host = qemu_vmalloc(size);
-#ifdef MADV_MERGEABLE
- madvise(new_block->host, size, MADV_MERGEABLE);
-#endif
+ qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
}
#else
fprintf(stderr, "-mem-path option unsupported\n");
@@ -2858,9 +2856,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
#else
new_block->host = qemu_vmalloc(size);
#endif
-#ifdef MADV_MERGEABLE
- madvise(new_block->host, size, MADV_MERGEABLE);
-#endif
+ qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
}
}
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 9fe3886..1e74674 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -51,8 +51,8 @@ static void balloon_page(void *addr, int deflate)
{
#if defined(__linux__)
if (!kvm_enabled() || kvm_has_sync_mmu())
- madvise(addr, TARGET_PAGE_SIZE,
- deflate ? MADV_WILLNEED : MADV_DONTNEED);
+ qemu_madvise(addr, TARGET_PAGE_SIZE,
+ deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED);
#endif
}
diff --git a/kvm-all.c b/kvm-all.c
index 58b0404..1cc696f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1031,18 +1031,14 @@ int kvm_has_xcrs(void)
void kvm_setup_guest_memory(void *start, size_t size)
{
if (!kvm_has_sync_mmu()) {
-#ifdef MADV_DONTFORK
- int ret = madvise(start, size, MADV_DONTFORK);
+ int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK);
if (ret) {
- perror("madvice");
+ perror("qemu_madvise");
+ fprintf(stderr,
+ "Need MADV_DONTFORK in absence of synchronous KVM MMU\n");
exit(1);
}
-#else
- fprintf(stderr,
- "Need MADV_DONTFORK in absence of synchronous KVM MMU\n");
- exit(1);
-#endif
}
}
diff --git a/osdep.c b/osdep.c
index 30426ff..2e05b21 100644
--- a/osdep.c
+++ b/osdep.c
@@ -32,9 +32,16 @@
/* Needed early for CONFIG_BSD etc. */
#include "config-host.h"
+#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
+#include <sys/mman.h>
+#endif
+
#ifdef CONFIG_SOLARIS
#include <sys/types.h>
#include <sys/statvfs.h>
+/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
+ discussion about Solaris header problems */
+extern int madvise(caddr_t, size_t, int);
#endif
#ifdef CONFIG_EVENTFD
@@ -139,6 +146,22 @@ void qemu_vfree(void *ptr)
#endif
+int qemu_madvise(void *addr, size_t len, int advice)
+{
+ if (advice == QEMU_MADV_INVALID) {
+ errno = EINVAL;
+ return -1;
+ }
+#if defined(CONFIG_MADVISE)
+ return madvise(addr, len, advice);
+#elif defined(CONFIG_POSIX_MADVISE)
+ return posix_madvise(addr, len, advice);
+#else
+ errno = EINVAL;
+ return -1;
+#endif
+}
+
int qemu_create_pidfile(const char *filename)
{
char buffer[128];
diff --git a/osdep.h b/osdep.h
index 1cdc7e2..6716281 100644
--- a/osdep.h
+++ b/osdep.h
@@ -90,6 +90,41 @@ void *qemu_memalign(size_t alignment, size_t size);
void *qemu_vmalloc(size_t size);
void qemu_vfree(void *ptr);
+#define QEMU_MADV_INVALID -1
+
+#if defined(CONFIG_MADVISE)
+
+#define QEMU_MADV_WILLNEED MADV_WILLNEED
+#define QEMU_MADV_DONTNEED MADV_DONTNEED
+#ifdef MADV_DONTFORK
+#define QEMU_MADV_DONTFORK MADV_DONTFORK
+#else
+#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
+#endif
+#ifdef MADV_MERGEABLE
+#define QEMU_MADV_MERGEABLE MADV_MERGEABLE
+#else
+#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
+#endif
+
+#elif defined(CONFIG_POSIX_MADVISE)
+
+#define QEMU_MADV_WILLNEED POSIX_MADV_WILLNEED
+#define QEMU_MADV_DONTNEED POSIX_MADV_DONTNEED
+#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
+#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
+
+#else /* no-op */
+
+#define QEMU_MADV_WILLNEED QEMU_MADV_INVALID
+#define QEMU_MADV_DONTNEED QEMU_MADV_INVALID
+#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
+#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
+
+#endif
+
+int qemu_madvise(void *addr, size_t len, int advice);
+
int qemu_create_pidfile(const char *filename);
#ifdef _WIN32
diff --git a/vl.c b/vl.c
index 3f45aa9..d352d18 100644
--- a/vl.c
+++ b/vl.c
@@ -80,9 +80,6 @@
#include <net/if.h>
#include <syslog.h>
#include <stropts.h>
-/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
- discussion about Solaris header problems */
-extern int madvise(caddr_t, size_t, int);
#endif
#endif
#endif
commit d63cb48db9016328a7a69f3a1c2938cd3dfc9d1a
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date: Mon Sep 20 19:08:42 2010 +0200
powerpc: Make the decr interrupt type overridable
Make it possible for boards to override the kind of interrupt
to be signaled when the decr timer hits. The 405's signal PIT
interrupts while the 440's signal DECR.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
diff --git a/hw/ppc.c b/hw/ppc.c
index 55e3808..968aec1 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -769,6 +769,9 @@ struct ppcemb_timer_t {
struct QEMUTimer *fit_timer;
uint64_t wdt_next; /* Tick for next WDT interrupt */
struct QEMUTimer *wdt_timer;
+
+ /* 405 have the PIT, 440 have a DECR. */
+ unsigned int decr_excp;
};
/* Fixed interval timer */
@@ -851,7 +854,7 @@ static void cpu_4xx_pit_cb (void *opaque)
ppcemb_timer = tb_env->opaque;
env->spr[SPR_40x_TSR] |= 1 << 27;
if ((env->spr[SPR_40x_TCR] >> 26) & 0x1)
- ppc_set_irq(env, PPC_INTERRUPT_PIT, 1);
+ ppc_set_irq(env, ppcemb_timer->decr_excp, 1);
start_stop_pit(env, tb_env, 1);
LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " "
"%016" PRIx64 "\n", __func__,
@@ -948,10 +951,15 @@ target_ulong load_40x_pit (CPUState *env)
void store_booke_tsr (CPUState *env, target_ulong val)
{
+ ppc_tb_t *tb_env = env->tb_env;
+ ppcemb_timer_t *ppcemb_timer;
+
+ ppcemb_timer = tb_env->opaque;
+
LOG_TB("%s: val " TARGET_FMT_lx "\n", __func__, val);
env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000);
if (val & 0x80000000)
- ppc_set_irq(env, PPC_INTERRUPT_PIT, 0);
+ ppc_set_irq(env, ppcemb_timer->decr_excp, 0);
}
void store_booke_tcr (CPUState *env, target_ulong val)
@@ -977,7 +985,8 @@ static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq)
/* XXX: we should also update all timers */
}
-clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
+clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq,
+ unsigned int decr_excp)
{
ppc_tb_t *tb_env;
ppcemb_timer_t *ppcemb_timer;
@@ -996,6 +1005,7 @@ clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
qemu_new_timer(vm_clock, &cpu_4xx_fit_cb, env);
ppcemb_timer->wdt_timer =
qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env);
+ ppcemb_timer->decr_excp = decr_excp;
}
return &ppc_emb_set_tb_clk;
diff --git a/hw/ppc.h b/hw/ppc.h
index 1251932..34f54cf 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -19,7 +19,9 @@ int ppc_dcr_init (CPUState *env, int (*dcr_read_error)(int dcrn),
int (*dcr_write_error)(int dcrn));
int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
dcr_read_cb drc_read, dcr_write_cb dcr_write);
-clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq);
+clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq,
+ unsigned int decr_excp);
+
/* Embedded PowerPC reset */
void ppc40x_core_reset (CPUState *env);
void ppc40x_chip_reset (CPUState *env);
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index 7f698b8..5f581fe 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -56,7 +56,7 @@ CPUState *ppc4xx_init (const char *cpu_model,
cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
cpu_clk->opaque = env;
/* Set time-base frequency to sysclk */
- tb_clk->cb = ppc_emb_timers_init(env, sysclk);
+ tb_clk->cb = ppc_emb_timers_init(env, sysclk, PPC_INTERRUPT_PIT);
tb_clk->opaque = env;
ppc_dcr_init(env, NULL, NULL);
/* Register qemu callbacks */
commit a586e548fb41afa21291bcc96f0a657d5ceaad59
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date: Mon Sep 20 19:06:32 2010 +0200
powerpc: Improve emulation of the BookE MMU
Improve the emulation of the BookE MMU to be able to boot linux
on virtex5 boards.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 9c8d774..dc1f4b8 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -453,6 +453,9 @@ struct ppc_slb_t {
#endif
#endif
+/* Exception state register bits definition */
+#define ESR_ST 23 /* Exception was caused by a store type access. */
+
enum {
POWERPC_FLAG_NONE = 0x00000000,
/* Flag for MSR bit 25 signification (VRE/SPE) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index f865d7a..3bc8a34 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1325,8 +1325,15 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
#endif
if ((access_type == ACCESS_CODE && msr_ir == 0) ||
(access_type != ACCESS_CODE && msr_dr == 0)) {
- /* No address translation */
- ret = check_physical(env, ctx, eaddr, rw);
+ if (env->mmu_model == POWERPC_MMU_BOOKE) {
+ /* The BookE MMU always performs address translation. The
+ IS and DS bits only affect the address space. */
+ ret = mmubooke_get_physical_address(env, ctx, eaddr,
+ rw, access_type);
+ } else {
+ /* No address translation. */
+ ret = check_physical(env, ctx, eaddr, rw);
+ }
} else {
ret = -1;
switch (env->mmu_model) {
@@ -1444,8 +1451,9 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
env->error_code = 0x40000000;
break;
case POWERPC_MMU_BOOKE:
- /* XXX: TODO */
- cpu_abort(env, "BookE MMU model is not implemented\n");
+ env->exception_index = POWERPC_EXCP_ITLB;
+ env->error_code = 0;
+ env->spr[SPR_BOOKE_DEAR] = address;
return -1;
case POWERPC_MMU_BOOKE_FSL:
/* XXX: TODO */
@@ -1471,6 +1479,9 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
break;
case -3:
/* No execute protection violation */
+ if (env->mmu_model == POWERPC_MMU_BOOKE) {
+ env->spr[SPR_BOOKE_ESR] = 0x00000000;
+ }
env->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x10000000;
break;
@@ -1556,8 +1567,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
cpu_abort(env, "MPC8xx MMU model is not implemented\n");
break;
case POWERPC_MMU_BOOKE:
- /* XXX: TODO */
- cpu_abort(env, "BookE MMU model is not implemented\n");
+ env->exception_index = POWERPC_EXCP_DTLB;
+ env->error_code = 0;
+ env->spr[SPR_BOOKE_DEAR] = address;
+ env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
return -1;
case POWERPC_MMU_BOOKE_FSL:
/* XXX: TODO */
@@ -1582,6 +1595,9 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
if (rw) {
env->spr[SPR_40x_ESR] |= 0x00800000;
}
+ } else if (env->mmu_model == POWERPC_MMU_BOOKE) {
+ env->spr[SPR_BOOKE_DEAR] = address;
+ env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
} else {
env->spr[SPR_DAR] = address;
if (rw == 1) {
@@ -1848,8 +1864,7 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
cpu_abort(env, "MPC8xx MMU model is not implemented\n");
break;
case POWERPC_MMU_BOOKE:
- /* XXX: TODO */
- cpu_abort(env, "BookE MMU model is not implemented\n");
+ tlb_flush(env, 1);
break;
case POWERPC_MMU_BOOKE_FSL:
/* XXX: TODO */
@@ -2607,6 +2622,13 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
/* Reset exception state */
env->exception_index = POWERPC_EXCP_NONE;
env->error_code = 0;
+
+ if (env->mmu_model == POWERPC_MMU_BOOKE) {
+ /* XXX: The BookE changes address space when switching modes,
+ we should probably implement that as different MMU indexes,
+ but for the moment we do it the slow way and flush all. */
+ tlb_flush(env, 1);
+ }
}
void do_interrupt (CPUState *env)
commit c973a36d178510790c148f88104b85016f59235a
Author: malc <av1474 at comtv.ru>
Date: Thu Sep 23 22:16:15 2010 +0400
fmopl: workaround for -Wempty-body
Signed-off-by: malc <av1474 at comtv.ru>
diff --git a/hw/fmopl.c b/hw/fmopl.c
index d1161f8..3df1806 100644
--- a/hw/fmopl.c
+++ b/hw/fmopl.c
@@ -1342,8 +1342,9 @@ unsigned char OPLRead(FM_OPL *OPL,int a)
{
if(OPL->keyboardhandler_r)
return OPL->keyboardhandler_r(OPL->keyboard_param);
- else
+ else {
LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
+ }
}
return 0;
#if 0
@@ -1355,8 +1356,9 @@ unsigned char OPLRead(FM_OPL *OPL,int a)
{
if(OPL->porthandler_r)
return OPL->porthandler_r(OPL->port_param);
- else
+ else {
LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
+ }
}
return 0;
case 0x1a: /* PCM-DATA */
commit 9c9e7d51bf01afdd4902bc9832c4a6ec19f68d0b
Author: Stefan Weil <weil at mail.berlios.de>
Date: Tue Sep 21 22:27:49 2010 +0200
Move macros GCC_ATTR and GCC_FMT_ATTR to common header file
By moving the definition of GCC_ATTR and GCC_FMT_ATTR
from audio_int.h to qemu-common.h these macros are
now generally available for further patches which add
the gcc format attribute.
Newer gcc versions support format gnu_printf which is
better suited for use in QEMU than format printf
(QEMU always uses standard format strings (even with mingw32)).
V2: Use correct operator '==' (instead of '=')
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 06e313f..d8560b6 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -236,14 +236,6 @@ static inline int audio_ring_dist (int dst, int src, int len)
return (dst >= src) ? (dst - src) : (len - src + dst);
}
-#if defined __GNUC__
-#define GCC_ATTR __attribute__ ((__unused__, __format__ (__printf__, 1, 2)))
-#define GCC_FMT_ATTR(n, m) __attribute__ ((__format__ (__printf__, n, m)))
-#else
-#define GCC_ATTR /**/
-#define GCC_FMT_ATTR(n, m)
-#endif
-
static void GCC_ATTR dolog (const char *fmt, ...)
{
va_list ap;
diff --git a/qemu-common.h b/qemu-common.h
index 5544ffd..88c5207 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -70,6 +70,22 @@ struct iovec {
#include <sys/uio.h>
#endif
+#if defined __GNUC__
+# if (__GNUC__ < 4) || \
+ defined(__GNUC_MINOR__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4)
+ /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */
+# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2)))
+# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
+# else
+ /* Use gnu_printf when supported (qemu uses standard format strings). */
+# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
+# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
+# endif
+#else
+#define GCC_ATTR /**/
+#define GCC_FMT_ATTR(n, m)
+#endif
+
#ifdef _WIN32
#define fsync _commit
#define lseek _lseeki64
commit 80bb8cba0af8a77341ef91ff9d5a2d84cad1880f
Author: Blue Swirl <blauwirbel at gmail.com>
Date: Wed Sep 22 19:51:33 2010 +0300
Fix OpenBSD build
Add #include <sys/types.h>, needed by #include <sys/socket.h>.
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/qemu_socket.h b/qemu_socket.h
index 164ae3e..897a8ae 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -17,6 +17,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
#else
+#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
commit 687db4ed2ecd5fd74c94fbb420482823cca4ab7e
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Wed Sep 22 14:46:33 2010 -0500
block-verify: fix 32-bit build
Reported-by: Peter Lemenkov <lemenkov at gmail.com>
Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
diff --git a/block/blkverify.c b/block/blkverify.c
index 4202685..8083464 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -58,7 +58,7 @@ static void blkverify_err(BlkverifyAIOCB *acb, const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "blkverify: %s sector_num=%ld nb_sectors=%d ",
+ fprintf(stderr, "blkverify: %s sector_num=%" PRId64 " nb_sectors=%d ",
acb->is_write ? "write" : "read", acb->sector_num,
acb->nb_sectors);
vfprintf(stderr, fmt, ap);
commit 879f0655579a1f94fab2cd20a1597aef9a3117ef
Author: Stefan Weil <weil at mail.berlios.de>
Date: Wed Sep 22 20:56:35 2010 +0200
Fix compilation error (missing include statement)
./hw/sd.c: In function âsd_initâ:
./hw/sd.c:443: error: implicit declaration of function âqemu_blockalignâ
./hw/sd.c:443: error: nested extern declaration of âqemu_blockalignâ
./hw/sd.c:443: error: assignment makes pointer from integer without a cast
Cc: Christoph Hellwig <hch at lst.de>
Cc: Kevin Wolf <kwolf at redhat.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
diff --git a/hw/sd.c b/hw/sd.c
index 4bcf1c0..601545b 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -31,6 +31,7 @@
#include "hw.h"
#include "block.h"
+#include "block_int.h"
#include "sd.h"
//#define DEBUG_SD 1
commit e1bb0a1a6c7c6d51443856ca90bd538b1ef5feeb
Merge: f36d53e... d9d3341...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date: Tue Sep 21 17:50:58 2010 -0500
Merge remote branch 'kwolf/for-anthony' into staging
commit f36d53ef6cb848d5cf204b0854b12e0359f0fd7e
Author: Stefan Weil <weil at mail.berlios.de>
Date: Mon Sep 20 22:18:01 2010 +0200
mips_malta: Fix format strings
Fix two compiler warnings (when format attribute is applied).
Cc: Aurelien Jarno <aurelien at aurel32.net>
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index ec95cd8..1cb7880 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -728,13 +728,13 @@ static int64_t load_kernel (void)
prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
prom_buf = qemu_malloc(prom_size);
- prom_set(prom_buf, prom_index++, loaderparams.kernel_filename);
+ prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
if (initrd_size > 0) {
prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
loaderparams.kernel_cmdline);
} else {
- prom_set(prom_buf, prom_index++, loaderparams.kernel_cmdline);
+ prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
}
prom_set(prom_buf, prom_index++, "memsize");
commit 1ed1139dc4772d0cc692a21fefb2ad598932d2be
Author: Stefan Weil <weil at mail.berlios.de>
Date: Mon Sep 20 22:18:00 2010 +0200
mips_fulong2e: Fix format strings
Fix two compiler warnings (when format attribute is applied)
and one error (missing %) in format strings.
Cc: Aurelien Jarno <aurelien at aurel32.net>
Cc: Blue Swirl <blauwirbel at gmail.com>
Signed-off-by: Stefan Weil <weil at mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index ac82067..61ca9c4 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -141,13 +141,13 @@ static int64_t load_kernel (CPUState *env)
prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
prom_buf = qemu_malloc(prom_size);
- prom_set(prom_buf, index++, loaderparams.kernel_filename);
+ prom_set(prom_buf, index++, "%s", loaderparams.kernel_filename);
if (initrd_size > 0) {
- prom_set(prom_buf, index++, "rd_start=0x" PRIx64 " rd_size=%li %s",
+ prom_set(prom_buf, index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
loaderparams.kernel_cmdline);
} else {
- prom_set(prom_buf, index++, loaderparams.kernel_cmdline);
+ prom_set(prom_buf, index++, "%s", loaderparams.kernel_cmdline);
}
/* Setup minimum environment variables */
commit 91f169004d9e9febbf9134c8fc068d6e04613b9c
Author: Andreas Färber <andreas.faerber at web.de>
Date: Sun Sep 12 17:21:36 2010 +0200
trace: Fix user emulator dependency on trace objects
On a clean build, after generating trace.h, make would recurse into *-*-user
without a clue how to build ../trace.o (added to $(obj-y) in Makefile.target)
since its generation rule is in the main Makefile.
The softmmus are seemingly unaffected because the $(TOOLS), which each have
a dependency on $(trace-obj-y), are built first for the build-all target.
Add a dependency on $(trace-obj-y) for %-user, as done for the qemu-* tools.
Let's be paranoid and do the same for %-softmmu while at it, just in case
someone messes with $(TOOLS) or calls the Makefile target directly.
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
Acked-by: Stefan Weil <weil at mail.berlios.de>
Cc: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Cc: Prerna Saxena <prerna at linux.vnet.ibm.com>
Cc: Blue Swirl <blauwirbel at gmail.com>
Cc: Anthony Liguori <aliguori at us.ibm.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
diff --git a/Makefile b/Makefile
index ab91d42..090d632 100644
--- a/Makefile
+++ b/Makefile
@@ -80,9 +80,9 @@ include $(SRC_PATH)/Makefile.objs
endif
$(common-obj-y): $(GENERATED_HEADERS)
-$(filter %-softmmu,$(SUBDIR_RULES)): $(common-obj-y) subdir-libdis
+$(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis
-$(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) subdir-libdis-user subdir-libuser
+$(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(trace-obj-y) subdir-libdis-user subdir-libuser
ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
romsubdir-%:
commit 869564a9c0f78b1972e1ac51e69cb2016af3b060
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Apr 13 09:05:03 2010 +0200
spice: add tablet support
Add support for the spice tablet interface. The tablet interface will
be registered (and then used by the spice client) as soon as a absolute
pointing device is available and used by the guest, i.e. you'll have to
configure your guest with '-usbdevice tablet'.
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 0bc230e..6702dfd 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -180,7 +180,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
surface.width = ds_get_width(ssd->ds);
surface.height = ds_get_height(ssd->ds);
surface.stride = -surface.width * 4;
- surface.mouse_mode = 0;
+ surface.mouse_mode = true;
surface.flags = 0;
surface.type = 0;
surface.mem = (intptr_t)ssd->buf;
diff --git a/ui/spice-input.c b/ui/spice-input.c
index 91cf18d..37c8578 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <stdbool.h>
#include <string.h>
#include <spice.h>
@@ -76,9 +77,13 @@ static void kbd_leds(void *opaque, int ledstate)
/* mouse bits */
-typedef struct QemuSpiceMouse {
- SpiceMouseInstance sin;
-} QemuSpiceMouse;
+typedef struct QemuSpicePointer {
+ SpiceMouseInstance mouse;
+ SpiceTabletInstance tablet;
+ int width, height, x, y;
+ Notifier mouse_mode;
+ bool absolute;
+} QemuSpicePointer;
static int map_buttons(int spice_buttons)
{
@@ -121,17 +126,92 @@ static const SpiceMouseInterface mouse_interface = {
.buttons = mouse_buttons,
};
+static void tablet_set_logical_size(SpiceTabletInstance* sin, int width, int height)
+{
+ QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+ if (height < 16) {
+ height = 16;
+ }
+ if (width < 16) {
+ width = 16;
+ }
+ pointer->width = width;
+ pointer->height = height;
+}
+
+static void tablet_position(SpiceTabletInstance* sin, int x, int y,
+ uint32_t buttons_state)
+{
+ QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+ pointer->x = x * 0x7FFF / (pointer->width - 1);
+ pointer->y = y * 0x7FFF / (pointer->height - 1);
+ kbd_mouse_event(pointer->x, pointer->y, 0, map_buttons(buttons_state));
+}
+
+
+static void tablet_wheel(SpiceTabletInstance* sin, int wheel,
+ uint32_t buttons_state)
+{
+ QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+ kbd_mouse_event(pointer->x, pointer->y, wheel, map_buttons(buttons_state));
+}
+
+static void tablet_buttons(SpiceTabletInstance *sin,
+ uint32_t buttons_state)
+{
+ QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
+
+ kbd_mouse_event(pointer->x, pointer->y, 0, map_buttons(buttons_state));
+}
+
+static const SpiceTabletInterface tablet_interface = {
+ .base.type = SPICE_INTERFACE_TABLET,
+ .base.description = "tablet",
+ .base.major_version = SPICE_INTERFACE_TABLET_MAJOR,
+ .base.minor_version = SPICE_INTERFACE_TABLET_MINOR,
+ .set_logical_size = tablet_set_logical_size,
+ .position = tablet_position,
+ .wheel = tablet_wheel,
+ .buttons = tablet_buttons,
+};
+
+static void mouse_mode_notifier(Notifier *notifier)
+{
+ QemuSpicePointer *pointer = container_of(notifier, QemuSpicePointer, mouse_mode);
+ bool is_absolute = kbd_mouse_is_absolute();
+
+ if (pointer->absolute == is_absolute) {
+ return;
+ }
+
+ if (is_absolute) {
+ qemu_spice_add_interface(&pointer->tablet.base);
+ } else {
+ spice_server_remove_interface(&pointer->tablet.base);
+ }
+ pointer->absolute = is_absolute;
+}
+
void qemu_spice_input_init(void)
{
QemuSpiceKbd *kbd;
- QemuSpiceMouse *mouse;
+ QemuSpicePointer *pointer;
kbd = qemu_mallocz(sizeof(*kbd));
kbd->sin.base.sif = &kbd_interface.base;
qemu_spice_add_interface(&kbd->sin.base);
qemu_add_led_event_handler(kbd_leds, kbd);
- mouse = qemu_mallocz(sizeof(*mouse));
- mouse->sin.base.sif = &mouse_interface.base;
- qemu_spice_add_interface(&mouse->sin.base);
+ pointer = qemu_mallocz(sizeof(*pointer));
+ pointer->mouse.base.sif = &mouse_interface.base;
+ pointer->tablet.base.sif = &tablet_interface.base;
+ qemu_spice_add_interface(&pointer->mouse.base);
+
+ pointer->absolute = false;
+ pointer->mouse_mode.notify = mouse_mode_notifier;
+ qemu_add_mouse_mode_change_notifier(&pointer->mouse_mode);
+ mouse_mode_notifier(&pointer->mouse_mode);
}
commit a3e2226031496f479b5fe4a069ec1acd68a17e8d
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Aug 25 15:32:06 2010 +0200
spice: simple display
With that patch applied you'll actually see the guests screen in the
spice client. This does *not* bring qxl and full spice support though.
This is basically the qxl vga mode made more generic, so it plays
together with any qemu-emulated gfx card. You can display stdvga or
cirrus via spice client. You can have both vnc and spice enabled and
clients connected at the same time.
diff --git a/Makefile.objs b/Makefile.objs
index a95106f..a3113d8 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -88,7 +88,7 @@ common-obj-y += pflib.o
common-obj-$(CONFIG_BRLAPI) += baum.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
-common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o
audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
audio-obj-$(CONFIG_SDL) += sdlaudio.o
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 175c961..063c7dc 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -29,6 +29,7 @@ extern int using_spice;
void qemu_spice_init(void);
void qemu_spice_input_init(void);
+void qemu_spice_display_init(DisplayState *ds);
int qemu_spice_add_interface(SpiceBaseInstance *sin);
#else /* CONFIG_SPICE */
diff --git a/ui/spice-display.c b/ui/spice-display.c
new file mode 100644
index 0000000..0bc230e
--- /dev/null
+++ b/ui/spice-display.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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 or
+ * (at your option) version 3 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <pthread.h>
+
+#include "qemu-common.h"
+#include "qemu-spice.h"
+#include "qemu-timer.h"
+#include "qemu-queue.h"
+#include "monitor.h"
+#include "console.h"
+#include "sysemu.h"
+
+#include "spice-display.h"
+
+static int debug = 0;
+
+static void __attribute__((format(printf,2,3)))
+dprint(int level, const char *fmt, ...)
+{
+ va_list args;
+
+ if (level <= debug) {
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ }
+}
+
+int qemu_spice_rect_is_empty(const QXLRect* r)
+{
+ return r->top == r->bottom || r->left == r->right;
+}
+
+void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
+{
+ if (qemu_spice_rect_is_empty(r)) {
+ return;
+ }
+
+ if (qemu_spice_rect_is_empty(dest)) {
+ *dest = *r;
+ return;
+ }
+
+ dest->top = MIN(dest->top, r->top);
+ dest->left = MIN(dest->left, r->left);
+ dest->bottom = MAX(dest->bottom, r->bottom);
+ dest->right = MAX(dest->right, r->right);
+}
+
+/*
+ * Called from spice server thread context (via interface_get_command).
+ * We do *not* hold the global qemu mutex here, so extra care is needed
+ * when calling qemu functions. Qemu interfaces used:
+ * - pflib (is re-entrant).
+ * - qemu_malloc (underlying glibc malloc is re-entrant).
+ */
+SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
+{
+ SimpleSpiceUpdate *update;
+ QXLDrawable *drawable;
+ QXLImage *image;
+ QXLCommand *cmd;
+ uint8_t *src, *dst;
+ int by, bw, bh;
+
+ if (qemu_spice_rect_is_empty(&ssd->dirty)) {
+ return NULL;
+ };
+
+ pthread_mutex_lock(&ssd->lock);
+ dprint(2, "%s: lr %d -> %d, tb -> %d -> %d\n", __FUNCTION__,
+ ssd->dirty.left, ssd->dirty.right,
+ ssd->dirty.top, ssd->dirty.bottom);
+
+ update = qemu_mallocz(sizeof(*update));
+ drawable = &update->drawable;
+ image = &update->image;
+ cmd = &update->ext.cmd;
+
+ bw = ssd->dirty.right - ssd->dirty.left;
+ bh = ssd->dirty.bottom - ssd->dirty.top;
+ update->bitmap = qemu_malloc(bw * bh * 4);
+
+ drawable->bbox = ssd->dirty;
+ drawable->clip.type = SPICE_CLIP_TYPE_NONE;
+ drawable->effect = QXL_EFFECT_OPAQUE;
+ drawable->release_info.id = (intptr_t)update;
+ drawable->type = QXL_DRAW_COPY;
+ drawable->surfaces_dest[0] = -1;
+ drawable->surfaces_dest[1] = -1;
+ drawable->surfaces_dest[2] = -1;
+
+ drawable->u.copy.rop_descriptor = SPICE_ROPD_OP_PUT;
+ drawable->u.copy.src_bitmap = (intptr_t)image;
+ drawable->u.copy.src_area.right = bw;
+ drawable->u.copy.src_area.bottom = bh;
+
+ QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_DEVICE, ssd->unique++);
+ image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
+ image->bitmap.flags = QXL_BITMAP_DIRECT | QXL_BITMAP_TOP_DOWN;
+ image->bitmap.stride = bw * 4;
+ image->descriptor.width = image->bitmap.x = bw;
+ image->descriptor.height = image->bitmap.y = bh;
+ image->bitmap.data = (intptr_t)(update->bitmap);
+ image->bitmap.palette = 0;
+ image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
+
+ if (ssd->conv == NULL) {
+ PixelFormat dst = qemu_default_pixelformat(32);
+ ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf);
+ assert(ssd->conv);
+ }
+
+ src = ds_get_data(ssd->ds) +
+ ssd->dirty.top * ds_get_linesize(ssd->ds) +
+ ssd->dirty.left * ds_get_bytes_per_pixel(ssd->ds);
+ dst = update->bitmap;
+ for (by = 0; by < bh; by++) {
+ qemu_pf_conv_run(ssd->conv, dst, src, bw);
+ src += ds_get_linesize(ssd->ds);
+ dst += image->bitmap.stride;
+ }
+
+ cmd->type = QXL_CMD_DRAW;
+ cmd->data = (intptr_t)drawable;
+
+ memset(&ssd->dirty, 0, sizeof(ssd->dirty));
+ pthread_mutex_unlock(&ssd->lock);
+ return update;
+}
+
+/*
+ * Called from spice server thread context (via interface_release_ressource)
+ * We do *not* hold the global qemu mutex here, so extra care is needed
+ * when calling qemu functions. Qemu interfaces used:
+ * - qemu_free (underlying glibc free is re-entrant).
+ */
+void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
+{
+ qemu_free(update->bitmap);
+ qemu_free(update);
+}
+
+void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
+{
+ QXLDevMemSlot memslot;
+
+ dprint(1, "%s:\n", __FUNCTION__);
+
+ memset(&memslot, 0, sizeof(memslot));
+ memslot.slot_group_id = MEMSLOT_GROUP_HOST;
+ memslot.virt_end = ~0;
+ ssd->worker->add_memslot(ssd->worker, &memslot);
+}
+
+void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
+{
+ QXLDevSurfaceCreate surface;
+
+ dprint(1, "%s: %dx%d\n", __FUNCTION__,
+ ds_get_width(ssd->ds), ds_get_height(ssd->ds));
+
+ surface.format = SPICE_SURFACE_FMT_32_xRGB;
+ surface.width = ds_get_width(ssd->ds);
+ surface.height = ds_get_height(ssd->ds);
+ surface.stride = -surface.width * 4;
+ surface.mouse_mode = 0;
+ surface.flags = 0;
+ surface.type = 0;
+ surface.mem = (intptr_t)ssd->buf;
+ surface.group_id = MEMSLOT_GROUP_HOST;
+ ssd->worker->create_primary_surface(ssd->worker, 0, &surface);
+}
+
+void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
+{
+ dprint(1, "%s:\n", __FUNCTION__);
+
+ ssd->worker->destroy_primary_surface(ssd->worker, 0);
+}
+
+void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
+{
+ SimpleSpiceDisplay *ssd = opaque;
+
+ if (running) {
+ ssd->worker->start(ssd->worker);
+ } else {
+ ssd->worker->stop(ssd->worker);
+ }
+ ssd->running = running;
+}
+
+/* display listener callbacks */
+
+void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
+ int x, int y, int w, int h)
+{
+ QXLRect update_area;
+
+ dprint(2, "%s: x %d y %d w %d h %d\n", __FUNCTION__, x, y, w, h);
+ update_area.left = x,
+ update_area.right = x + w;
+ update_area.top = y;
+ update_area.bottom = y + h;
+
+ pthread_mutex_lock(&ssd->lock);
+ if (qemu_spice_rect_is_empty(&ssd->dirty)) {
+ ssd->notify++;
+ }
+ qemu_spice_rect_union(&ssd->dirty, &update_area);
+ pthread_mutex_unlock(&ssd->lock);
+}
+
+void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
+{
+ dprint(1, "%s:\n", __FUNCTION__);
+
+ pthread_mutex_lock(&ssd->lock);
+ memset(&ssd->dirty, 0, sizeof(ssd->dirty));
+ qemu_pf_conv_put(ssd->conv);
+ ssd->conv = NULL;
+ pthread_mutex_unlock(&ssd->lock);
+
+ qemu_spice_destroy_host_primary(ssd);
+ qemu_spice_create_host_primary(ssd);
+
+ pthread_mutex_lock(&ssd->lock);
+ memset(&ssd->dirty, 0, sizeof(ssd->dirty));
+ ssd->notify++;
+ pthread_mutex_unlock(&ssd->lock);
+}
+
+void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
+{
+ dprint(3, "%s:\n", __FUNCTION__);
+ vga_hw_update();
+ if (ssd->notify) {
+ ssd->notify = 0;
+ ssd->worker->wakeup(ssd->worker);
+ dprint(2, "%s: notify\n", __FUNCTION__);
+ }
+}
+
+/* spice display interface callbacks */
+
+static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
+{
+ SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+
+ dprint(1, "%s:\n", __FUNCTION__);
+ ssd->worker = qxl_worker;
+}
+
+static void interface_set_compression_level(QXLInstance *sin, int level)
+{
+ dprint(1, "%s:\n", __FUNCTION__);
+ /* nothing to do */
+}
+
+static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
+{
+ dprint(3, "%s:\n", __FUNCTION__);
+ /* nothing to do */
+}
+
+static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
+{
+ SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+
+ info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
+ info->memslot_id_bits = MEMSLOT_SLOT_BITS;
+ info->num_memslots = NUM_MEMSLOTS;
+ info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
+ info->internal_groupslot_id = 0;
+ info->qxl_ram_size = ssd->bufsize;
+ info->n_surfaces = NUM_SURFACES;
+}
+
+static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+{
+ SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+ SimpleSpiceUpdate *update;
+
+ dprint(3, "%s:\n", __FUNCTION__);
+ update = qemu_spice_create_update(ssd);
+ if (update == NULL) {
+ return false;
+ }
+ *ext = update->ext;
+ return true;
+}
+
+static int interface_req_cmd_notification(QXLInstance *sin)
+{
+ dprint(1, "%s:\n", __FUNCTION__);
+ return 1;
+}
+
+static void interface_release_resource(QXLInstance *sin,
+ struct QXLReleaseInfoExt ext)
+{
+ SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+ uintptr_t id;
+
+ dprint(2, "%s:\n", __FUNCTION__);
+ id = ext.info->id;
+ qemu_spice_destroy_update(ssd, (void*)id);
+}
+
+static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext)
+{
+ dprint(3, "%s:\n", __FUNCTION__);
+ return false;
+}
+
+static int interface_req_cursor_notification(QXLInstance *sin)
+{
+ dprint(1, "%s:\n", __FUNCTION__);
+ return 1;
+}
+
+static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
+{
+ fprintf(stderr, "%s: abort()\n", __FUNCTION__);
+ abort();
+}
+
+static int interface_flush_resources(QXLInstance *sin)
+{
+ fprintf(stderr, "%s: abort()\n", __FUNCTION__);
+ abort();
+ return 0;
+}
+
+static const QXLInterface dpy_interface = {
+ .base.type = SPICE_INTERFACE_QXL,
+ .base.description = "qemu simple display",
+ .base.major_version = SPICE_INTERFACE_QXL_MAJOR,
+ .base.minor_version = SPICE_INTERFACE_QXL_MINOR,
+
+ .attache_worker = interface_attach_worker,
+ .set_compression_level = interface_set_compression_level,
+ .set_mm_time = interface_set_mm_time,
+ .get_init_info = interface_get_init_info,
+
+ /* the callbacks below are called from spice server thread context */
+ .get_command = interface_get_command,
+ .req_cmd_notification = interface_req_cmd_notification,
+ .release_resource = interface_release_resource,
+ .get_cursor_command = interface_get_cursor_command,
+ .req_cursor_notification = interface_req_cursor_notification,
+ .notify_update = interface_notify_update,
+ .flush_resources = interface_flush_resources,
+};
+
+static SimpleSpiceDisplay sdpy;
+
+static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
+{
+ qemu_spice_display_update(&sdpy, x, y, w, h);
+}
+
+static void display_resize(struct DisplayState *ds)
+{
+ qemu_spice_display_resize(&sdpy);
+}
+
+static void display_refresh(struct DisplayState *ds)
+{
+ qemu_spice_display_refresh(&sdpy);
+}
+
+static DisplayChangeListener display_listener = {
+ .dpy_update = display_update,
+ .dpy_resize = display_resize,
+ .dpy_refresh = display_refresh,
+};
+
+void qemu_spice_display_init(DisplayState *ds)
+{
+ assert(sdpy.ds == NULL);
+ sdpy.ds = ds;
+ sdpy.bufsize = (16 * 1024 * 1024);
+ sdpy.buf = qemu_malloc(sdpy.bufsize);
+ pthread_mutex_init(&sdpy.lock, NULL);
+ register_displaychangelistener(ds, &display_listener);
+
+ sdpy.qxl.base.sif = &dpy_interface.base;
+ qemu_spice_add_interface(&sdpy.qxl.base);
+ assert(sdpy.worker);
+
+ qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy);
+ qemu_spice_create_host_memslot(&sdpy);
+ qemu_spice_create_host_primary(&sdpy);
+}
diff --git a/ui/spice-display.h b/ui/spice-display.h
new file mode 100644
index 0000000..e17671c
--- /dev/null
+++ b/ui/spice-display.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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 or
+ * (at your option) version 3 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <spice/ipc_ring.h>
+#include <spice/enums.h>
+#include <spice/qxl_dev.h>
+
+#include "pflib.h"
+
+#define NUM_MEMSLOTS 8
+#define MEMSLOT_GENERATION_BITS 8
+#define MEMSLOT_SLOT_BITS 8
+
+#define MEMSLOT_GROUP_HOST 0
+#define MEMSLOT_GROUP_GUEST 1
+#define NUM_MEMSLOTS_GROUPS 2
+
+#define NUM_SURFACES 1024
+
+typedef struct SimpleSpiceDisplay {
+ DisplayState *ds;
+ void *buf;
+ int bufsize;
+ QXLWorker *worker;
+ QXLInstance qxl;
+ uint32_t unique;
+ QemuPfConv *conv;
+
+ pthread_mutex_t lock;
+ QXLRect dirty;
+ int notify;
+ int running;
+} SimpleSpiceDisplay;
+
+typedef struct SimpleSpiceUpdate {
+ QXLDrawable drawable;
+ QXLImage image;
+ QXLCommandExt ext;
+ uint8_t *bitmap;
+} SimpleSpiceUpdate;
+
+int qemu_spice_rect_is_empty(const QXLRect* r);
+void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
+
+SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *sdpy);
+void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update);
+void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
+void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
+void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
+void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
+
+void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
+ int x, int y, int w, int h);
+void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
+void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
diff --git a/vl.c b/vl.c
index 27d9392..ee4f8c8 100644
--- a/vl.c
+++ b/vl.c
@@ -2931,6 +2931,8 @@ int main(int argc, char **argv, char **envp)
/* just use the first displaystate for the moment */
ds = get_displaystate();
+ if (using_spice)
+ display_remote++;
if (display_type == DT_DEFAULT && !display_remote) {
#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
display_type = DT_SDL;
@@ -2973,6 +2975,11 @@ int main(int argc, char **argv, char **envp)
printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
}
}
+#ifdef CONFIG_SPICE
+ if (using_spice) {
+ qemu_spice_display_init(ds);
+ }
+#endif
/* display setup */
dpy_resize(ds);
commit 78dd9ac1ca5130ae144a6abe8361a59483a5464b
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Thu Mar 11 11:13:29 2010 -0300
spice: add mouse
Open mouse channel. Now you can move the guests mouse pointer.
No tablet / absolute positioning (yet) though.
diff --git a/ui/spice-input.c b/ui/spice-input.c
index 5538a79..91cf18d 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -74,12 +74,64 @@ static void kbd_leds(void *opaque, int ledstate)
spice_server_kbd_leds(&kbd->sin, ledstate);
}
+/* mouse bits */
+
+typedef struct QemuSpiceMouse {
+ SpiceMouseInstance sin;
+} QemuSpiceMouse;
+
+static int map_buttons(int spice_buttons)
+{
+ int qemu_buttons = 0;
+
+ /*
+ * Note: SPICE_MOUSE_BUTTON_* specifies the wire protocol but this
+ * isn't what we get passed in via interface callbacks for the
+ * middle and right button ...
+ */
+ if (spice_buttons & SPICE_MOUSE_BUTTON_MASK_LEFT) {
+ qemu_buttons |= MOUSE_EVENT_LBUTTON;
+ }
+ if (spice_buttons & 0x04 /* SPICE_MOUSE_BUTTON_MASK_MIDDLE */) {
+ qemu_buttons |= MOUSE_EVENT_MBUTTON;
+ }
+ if (spice_buttons & 0x02 /* SPICE_MOUSE_BUTTON_MASK_RIGHT */) {
+ qemu_buttons |= MOUSE_EVENT_RBUTTON;
+ }
+ return qemu_buttons;
+}
+
+static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz,
+ uint32_t buttons_state)
+{
+ kbd_mouse_event(dx, dy, dz, map_buttons(buttons_state));
+}
+
+static void mouse_buttons(SpiceMouseInstance *sin, uint32_t buttons_state)
+{
+ kbd_mouse_event(0, 0, 0, map_buttons(buttons_state));
+}
+
+static const SpiceMouseInterface mouse_interface = {
+ .base.type = SPICE_INTERFACE_MOUSE,
+ .base.description = "mouse",
+ .base.major_version = SPICE_INTERFACE_MOUSE_MAJOR,
+ .base.minor_version = SPICE_INTERFACE_MOUSE_MINOR,
+ .motion = mouse_motion,
+ .buttons = mouse_buttons,
+};
+
void qemu_spice_input_init(void)
{
QemuSpiceKbd *kbd;
+ QemuSpiceMouse *mouse;
kbd = qemu_mallocz(sizeof(*kbd));
kbd->sin.base.sif = &kbd_interface.base;
qemu_spice_add_interface(&kbd->sin.base);
qemu_add_led_event_handler(kbd_leds, kbd);
+
+ mouse = qemu_mallocz(sizeof(*mouse));
+ mouse->sin.base.sif = &mouse_interface.base;
+ qemu_spice_add_interface(&mouse->sin.base);
}
commit 864401c2a709bcb66182c02372fb60a30055a4d7
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Thu Mar 11 11:13:28 2010 -0300
spice: add keyboard
Open keyboard channel. Now you can type into the spice client and the
keyboard events are sent to your guest. You'll need some other display
like vnc to actually see the guest responding to them though.
diff --git a/Makefile.objs b/Makefile.objs
index 2b58109..a95106f 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -88,7 +88,7 @@ common-obj-y += pflib.o
common-obj-$(CONFIG_BRLAPI) += baum.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
-common-obj-$(CONFIG_SPICE) += ui/spice-core.o
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o
audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
audio-obj-$(CONFIG_SDL) += sdlaudio.o
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 50faefb..175c961 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -28,6 +28,7 @@
extern int using_spice;
void qemu_spice_init(void);
+void qemu_spice_input_init(void);
int qemu_spice_add_interface(SpiceBaseInstance *sin);
#else /* CONFIG_SPICE */
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 006604b..8b5e4a8 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -167,6 +167,8 @@ void qemu_spice_init(void)
spice_server_init(spice_server, &core_interface);
using_spice = 1;
+
+ qemu_spice_input_init();
}
int qemu_spice_add_interface(SpiceBaseInstance *sin)
diff --git a/ui/spice-input.c b/ui/spice-input.c
new file mode 100644
index 0000000..5538a79
--- /dev/null
+++ b/ui/spice-input.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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 or
+ * (at your option) version 3 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <spice.h>
+#include <spice/enums.h>
+
+#include "qemu-common.h"
+#include "qemu-spice.h"
+#include "console.h"
+
+/* keyboard bits */
+
+typedef struct QemuSpiceKbd {
+ SpiceKbdInstance sin;
+ int ledstate;
+} QemuSpiceKbd;
+
+static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag);
+static uint8_t kbd_get_leds(SpiceKbdInstance *sin);
+static void kbd_leds(void *opaque, int l);
+
+static const SpiceKbdInterface kbd_interface = {
+ .base.type = SPICE_INTERFACE_KEYBOARD,
+ .base.description = "qemu keyboard",
+ .base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR,
+ .base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR,
+ .push_scan_freg = kbd_push_key,
+ .get_leds = kbd_get_leds,
+};
+
+static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
+{
+ kbd_put_keycode(frag);
+}
+
+static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
+{
+ QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin);
+ return kbd->ledstate;
+}
+
+static void kbd_leds(void *opaque, int ledstate)
+{
+ QemuSpiceKbd *kbd = opaque;
+
+ kbd->ledstate = 0;
+ if (ledstate & QEMU_SCROLL_LOCK_LED) {
+ kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK;
+ }
+ if (ledstate & QEMU_NUM_LOCK_LED) {
+ kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK;
+ }
+ if (ledstate & QEMU_CAPS_LOCK_LED) {
+ kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK;
+ }
+ spice_server_kbd_leds(&kbd->sin, ledstate);
+}
+
+void qemu_spice_input_init(void)
+{
+ QemuSpiceKbd *kbd;
+
+ kbd = qemu_mallocz(sizeof(*kbd));
+ kbd->sin.base.sif = &kbd_interface.base;
+ qemu_spice_add_interface(&kbd->sin.base);
+ qemu_add_led_event_handler(kbd_leds, kbd);
+}
commit 29b0040be6371c403dae0fef7fec36b814e300e8
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Thu Mar 11 11:13:27 2010 -0300
spice: core bits
Add -spice command line switch. Has support setting passwd and port for
now. With this patch applied the spice client can successfully connect
to qemu. You can't do anything useful yet though.
diff --git a/Makefile.objs b/Makefile.objs
index 8268574..2b58109 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -88,6 +88,8 @@ common-obj-y += pflib.o
common-obj-$(CONFIG_BRLAPI) += baum.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o
+
audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
audio-obj-$(CONFIG_SDL) += sdlaudio.o
audio-obj-$(CONFIG_OSS) += ossaudio.o
diff --git a/qemu-config.c b/qemu-config.c
index e3b746c..5c6ae63 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -351,6 +351,24 @@ static QemuOptsList qemu_cpudef_opts = {
},
};
+QemuOptsList qemu_spice_opts = {
+ .name = "spice",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head),
+ .desc = {
+ {
+ .name = "port",
+ .type = QEMU_OPT_NUMBER,
+ },{
+ .name = "password",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "disable-ticketing",
+ .type = QEMU_OPT_BOOL,
+ },
+ { /* end if list */ }
+ },
+};
+
static QemuOptsList *vm_config_groups[32] = {
&qemu_drive_opts,
&qemu_chardev_opts,
diff --git a/qemu-config.h b/qemu-config.h
index 533a049..20d707f 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -3,6 +3,7 @@
extern QemuOptsList qemu_fsdev_opts;
extern QemuOptsList qemu_virtfs_opts;
+extern QemuOptsList qemu_spice_opts;
QemuOptsList *qemu_find_opts(const char *group);
void qemu_add_opts(QemuOptsList *list);
diff --git a/qemu-options.hx b/qemu-options.hx
index a0b5ae9..718d47a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -670,6 +670,27 @@ STEXI
Enable SDL.
ETEXI
+DEF("spice", HAS_ARG, QEMU_OPTION_spice,
+ "-spice <args> enable spice\n", QEMU_ARCH_ALL)
+STEXI
+ at item -spice @var{option}[, at var{option}[,...]]
+ at findex -spice
+Enable the spice remote desktop protocol. Valid options are
+
+ at table @option
+
+ at item port=<nr>
+Set the TCP port spice is listening on.
+
+ at item password=<secret>
+Set the password you need to authenticate.
+
+ at item disable-ticketing
+Allow client connects without authentication.
+
+ at end table
+ETEXI
+
DEF("portrait", 0, QEMU_OPTION_portrait,
"-portrait rotate graphical output 90 deg left (only PXA LCD)\n",
QEMU_ARCH_ALL)
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
new file mode 100644
index 0000000..50faefb
--- /dev/null
+++ b/ui/qemu-spice.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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 or
+ * (at your option) version 3 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_SPICE_H
+#define QEMU_SPICE_H
+
+#ifdef CONFIG_SPICE
+
+#include <spice.h>
+
+#include "qemu-option.h"
+#include "qemu-config.h"
+
+extern int using_spice;
+
+void qemu_spice_init(void);
+int qemu_spice_add_interface(SpiceBaseInstance *sin);
+
+#else /* CONFIG_SPICE */
+
+#define using_spice 0
+
+#endif /* CONFIG_SPICE */
+
+#endif /* QEMU_SPICE_H */
diff --git a/ui/spice-core.c b/ui/spice-core.c
new file mode 100644
index 0000000..006604b
--- /dev/null
+++ b/ui/spice-core.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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 or
+ * (at your option) version 3 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <spice.h>
+#include <spice-experimental.h>
+
+#include "qemu-common.h"
+#include "qemu-spice.h"
+#include "qemu-timer.h"
+#include "qemu-queue.h"
+#include "monitor.h"
+
+/* core bits */
+
+static SpiceServer *spice_server;
+int using_spice = 0;
+
+struct SpiceTimer {
+ QEMUTimer *timer;
+ QTAILQ_ENTRY(SpiceTimer) next;
+};
+static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
+
+static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
+{
+ SpiceTimer *timer;
+
+ timer = qemu_mallocz(sizeof(*timer));
+ timer->timer = qemu_new_timer(rt_clock, func, opaque);
+ QTAILQ_INSERT_TAIL(&timers, timer, next);
+ return timer;
+}
+
+static void timer_start(SpiceTimer *timer, uint32_t ms)
+{
+ qemu_mod_timer(timer->timer, qemu_get_clock(rt_clock) + ms);
+}
+
+static void timer_cancel(SpiceTimer *timer)
+{
+ qemu_del_timer(timer->timer);
+}
+
+static void timer_remove(SpiceTimer *timer)
+{
+ qemu_del_timer(timer->timer);
+ qemu_free_timer(timer->timer);
+ QTAILQ_REMOVE(&timers, timer, next);
+ qemu_free(timer);
+}
+
+struct SpiceWatch {
+ int fd;
+ int event_mask;
+ SpiceWatchFunc func;
+ void *opaque;
+ QTAILQ_ENTRY(SpiceWatch) next;
+};
+static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches);
+
+static void watch_read(void *opaque)
+{
+ SpiceWatch *watch = opaque;
+ watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
+}
+
+static void watch_write(void *opaque)
+{
+ SpiceWatch *watch = opaque;
+ watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
+}
+
+static void watch_update_mask(SpiceWatch *watch, int event_mask)
+{
+ IOHandler *on_read = NULL;
+ IOHandler *on_write = NULL;
+
+ watch->event_mask = event_mask;
+ if (watch->event_mask & SPICE_WATCH_EVENT_READ) {
+ on_read = watch_read;
+ }
+ if (watch->event_mask & SPICE_WATCH_EVENT_WRITE) {
+ on_read = watch_write;
+ }
+ qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
+}
+
+static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
+{
+ SpiceWatch *watch;
+
+ watch = qemu_mallocz(sizeof(*watch));
+ watch->fd = fd;
+ watch->func = func;
+ watch->opaque = opaque;
+ QTAILQ_INSERT_TAIL(&watches, watch, next);
+
+ watch_update_mask(watch, event_mask);
+ return watch;
+}
+
+static void watch_remove(SpiceWatch *watch)
+{
+ watch_update_mask(watch, 0);
+ QTAILQ_REMOVE(&watches, watch, next);
+ qemu_free(watch);
+}
+
+static SpiceCoreInterface core_interface = {
+ .base.type = SPICE_INTERFACE_CORE,
+ .base.description = "qemu core services",
+ .base.major_version = SPICE_INTERFACE_CORE_MAJOR,
+ .base.minor_version = SPICE_INTERFACE_CORE_MINOR,
+
+ .timer_add = timer_add,
+ .timer_start = timer_start,
+ .timer_cancel = timer_cancel,
+ .timer_remove = timer_remove,
+
+ .watch_add = watch_add,
+ .watch_update_mask = watch_update_mask,
+ .watch_remove = watch_remove,
+};
+
+/* functions for the rest of qemu */
+
+void qemu_spice_init(void)
+{
+ QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
+ const char *password;
+ int port;
+
+ if (!opts) {
+ return;
+ }
+ port = qemu_opt_get_number(opts, "port", 0);
+ if (!port) {
+ return;
+ }
+ password = qemu_opt_get(opts, "password");
+
+ spice_server = spice_server_new();
+ spice_server_set_port(spice_server, port);
+ if (password) {
+ spice_server_set_ticket(spice_server, password, 0, 0, 0);
+ }
+ if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) {
+ spice_server_set_noauth(spice_server);
+ }
+
+ /* TODO: make configurable via cmdline */
+ spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ);
+
+ spice_server_init(spice_server, &core_interface);
+ using_spice = 1;
+}
+
+int qemu_spice_add_interface(SpiceBaseInstance *sin)
+{
+ return spice_server_add_interface(spice_server, sin);
+}
+
+static void spice_register_config(void)
+{
+ qemu_add_opts(&qemu_spice_opts);
+}
+machine_init(spice_register_config);
+
+static void spice_initialize(void)
+{
+ qemu_spice_init();
+}
+device_init(spice_initialize);
diff --git a/vl.c b/vl.c
index 2edc853..27d9392 100644
--- a/vl.c
+++ b/vl.c
@@ -165,6 +165,8 @@ int main(int argc, char **argv)
#include "cpus.h"
#include "arch_init.h"
+#include "ui/qemu-spice.h"
+
//#define DEBUG_NET
//#define DEBUG_SLIRP
@@ -2616,6 +2618,18 @@ int main(int argc, char **argv, char **envp)
}
break;
}
+ case QEMU_OPTION_spice:
+ olist = qemu_find_opts("spice");
+ if (!olist) {
+ fprintf(stderr, "spice is not supported by this qemu build.\n");
+ exit(1);
+ }
+ opts = qemu_opts_parse(olist, optarg, 0);
+ if (!opts) {
+ fprintf(stderr, "parse error: %s\n", optarg);
+ exit(1);
+ }
+ break;
case QEMU_OPTION_writeconfig:
{
FILE *fp;
commit cd4ec0b4d169faba8cc03a16b361700e32a83bd6
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Mar 24 10:26:51 2010 +0100
add spice into the configure file
diff --git a/configure b/configure
index 66b1d0b..695a632 100755
--- a/configure
+++ b/configure
@@ -325,6 +325,7 @@ user_pie="no"
zero_malloc=""
trace_backend="nop"
trace_file="trace"
+spice=""
# OS specific
if check_define __linux__ ; then
@@ -630,6 +631,10 @@ for opt do
;;
--enable-kvm) kvm="yes"
;;
+ --disable-spice) spice="no"
+ ;;
+ --enable-spice) spice="yes"
+ ;;
--enable-profiler) profiler="yes"
;;
--enable-cocoa)
@@ -912,6 +917,8 @@ echo " --enable-vhost-net enable vhost-net acceleration support"
echo " --trace-backend=B Trace backend nop simple ust"
echo " --trace-file=NAME Full PATH,NAME of file to store traces"
echo " Default:trace-<pid>"
+echo " --disable-spice disable spice"
+echo " --enable-spice enable spice"
echo ""
echo "NOTE: The object files are built at the place where configure is launched"
exit 1
@@ -2062,6 +2069,29 @@ if compile_prog "" ""; then
gcc_attribute_warn_unused_result=yes
fi
+# spice probe
+if test "$spice" != "no" ; then
+ cat > $TMPC << EOF
+#include <spice.h>
+int main(void) { spice_server_new(); return 0; }
+EOF
+ spice_cflags=$($pkgconfig --cflags spice-protocol spice-server 2>/dev/null)
+ spice_libs=$($pkgconfig --libs spice-protocol spice-server 2>/dev/null)
+ if $pkgconfig --atleast-version=0.5.3 spice-server &&\
+ compile_prog "$spice_cflags" "$spice_libs" ; then
+ spice="yes"
+ libs_softmmu="$libs_softmmu $spice_libs"
+ QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
+ else
+ if test "$spice" = "yes" ; then
+ feature_not_found "spice"
+ fi
+ spice="no"
+ fi
+fi
+
+##########################################
+
##########################################
# check if we have fdatasync
@@ -2245,6 +2275,7 @@ echo "uuid support $uuid"
echo "vhost-net support $vhost_net"
echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
+echo "spice support $spice"
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2482,6 +2513,10 @@ if test "$fdatasync" = "yes" ; then
echo "CONFIG_FDATASYNC=y" >> $config_host_mak
fi
+if test "$spice" = "yes" ; then
+ echo "CONFIG_SPICE=y" >> $config_host_mak
+fi
+
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
echo "CONFIG_BSD=y" >> $config_host_mak
commit da1d85e339730effd889978be5ae2caadd01bfa9
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Apr 23 13:44:10 2010 +0200
configure: add logging
Write compile commands and messages to config.log.
Useful for debugging configure.
diff --git a/configure b/configure
index 3bfc5e9..66b1d0b 100755
--- a/configure
+++ b/configure
@@ -16,15 +16,18 @@ TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.exe"
trap "rm -f $TMPC $TMPO $TMPE ; exit" EXIT INT QUIT TERM
+rm -f config.log
compile_object() {
- $cc $QEMU_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null
+ echo $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log
+ $cc $QEMU_CFLAGS -c -o $TMPO $TMPC >> config.log 2>&1
}
compile_prog() {
local_cflags="$1"
local_ldflags="$2"
- $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags > /dev/null 2> /dev/null
+ echo $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags >> config.log
+ $cc $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags >> config.log 2>&1
}
# check whether a command is available to this shell (may be either an
commit d6d94fc327af7e7c1343c091317e1ed8786906ad
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Mon Jun 14 09:54:27 2010 +0200
add pflib: PixelFormat conversion library.
diff --git a/Makefile.objs b/Makefile.objs
index 3ef6d80..8268574 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -83,6 +83,7 @@ common-obj-y += qemu-char.o savevm.o #aio.o
common-obj-y += msmouse.o ps2.o
common-obj-y += qdev.o qdev-properties.o
common-obj-y += block-migration.o
+common-obj-y += pflib.o
common-obj-$(CONFIG_BRLAPI) += baum.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
diff --git a/pflib.c b/pflib.c
new file mode 100644
index 0000000..1154d0c
--- /dev/null
+++ b/pflib.c
@@ -0,0 +1,213 @@
+/*
+ * PixelFormat conversion library.
+ *
+ * Author: Gerd Hoffmann <kraxel at redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#include "qemu-common.h"
+#include "console.h"
+#include "pflib.h"
+
+typedef struct QemuPixel QemuPixel;
+
+typedef void (*pf_convert)(QemuPfConv *conv,
+ void *dst, void *src, uint32_t cnt);
+typedef void (*pf_convert_from)(PixelFormat *pf,
+ QemuPixel *dst, void *src, uint32_t cnt);
+typedef void (*pf_convert_to)(PixelFormat *pf,
+ void *dst, QemuPixel *src, uint32_t cnt);
+
+struct QemuPfConv {
+ pf_convert convert;
+ PixelFormat src;
+ PixelFormat dst;
+
+ /* for copy_generic() */
+ pf_convert_from conv_from;
+ pf_convert_to conv_to;
+ QemuPixel *conv_buf;
+ uint32_t conv_cnt;
+};
+
+struct QemuPixel {
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+ uint8_t alpha;
+};
+
+/* ----------------------------------------------------------------------- */
+/* PixelFormat -> QemuPixel conversions */
+
+static void conv_16_to_pixel(PixelFormat *pf,
+ QemuPixel *dst, void *src, uint32_t cnt)
+{
+ uint16_t *src16 = src;
+
+ while (cnt > 0) {
+ dst->red = ((*src16 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
+ dst->green = ((*src16 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
+ dst->blue = ((*src16 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
+ dst->alpha = ((*src16 & pf->amask) >> pf->ashift) << (8 - pf->abits);
+ dst++, src16++, cnt--;
+ }
+}
+
+/* assumes pf->{r,g,b,a}bits == 8 */
+static void conv_32_to_pixel_fast(PixelFormat *pf,
+ QemuPixel *dst, void *src, uint32_t cnt)
+{
+ uint32_t *src32 = src;
+
+ while (cnt > 0) {
+ dst->red = (*src32 & pf->rmask) >> pf->rshift;
+ dst->green = (*src32 & pf->gmask) >> pf->gshift;
+ dst->blue = (*src32 & pf->bmask) >> pf->bshift;
+ dst->alpha = (*src32 & pf->amask) >> pf->ashift;
+ dst++, src32++, cnt--;
+ }
+}
+
+static void conv_32_to_pixel_generic(PixelFormat *pf,
+ QemuPixel *dst, void *src, uint32_t cnt)
+{
+ uint32_t *src32 = src;
+
+ while (cnt > 0) {
+ if (pf->rbits < 8) {
+ dst->red = ((*src32 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
+ } else {
+ dst->red = ((*src32 & pf->rmask) >> pf->rshift) >> (pf->rbits - 8);
+ }
+ if (pf->gbits < 8) {
+ dst->green = ((*src32 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
+ } else {
+ dst->green = ((*src32 & pf->gmask) >> pf->gshift) >> (pf->gbits - 8);
+ }
+ if (pf->bbits < 8) {
+ dst->blue = ((*src32 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
+ } else {
+ dst->blue = ((*src32 & pf->bmask) >> pf->bshift) >> (pf->bbits - 8);
+ }
+ if (pf->abits < 8) {
+ dst->alpha = ((*src32 & pf->amask) >> pf->ashift) << (8 - pf->abits);
+ } else {
+ dst->alpha = ((*src32 & pf->amask) >> pf->ashift) >> (pf->abits - 8);
+ }
+ dst++, src32++, cnt--;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+/* QemuPixel -> PixelFormat conversions */
+
+static void conv_pixel_to_16(PixelFormat *pf,
+ void *dst, QemuPixel *src, uint32_t cnt)
+{
+ uint16_t *dst16 = dst;
+
+ while (cnt > 0) {
+ *dst16 = ((uint16_t)src->red >> (8 - pf->rbits)) << pf->rshift;
+ *dst16 |= ((uint16_t)src->green >> (8 - pf->gbits)) << pf->gshift;
+ *dst16 |= ((uint16_t)src->blue >> (8 - pf->bbits)) << pf->bshift;
+ *dst16 |= ((uint16_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
+ dst16++, src++, cnt--;
+ }
+}
+
+static void conv_pixel_to_32(PixelFormat *pf,
+ void *dst, QemuPixel *src, uint32_t cnt)
+{
+ uint32_t *dst32 = dst;
+
+ while (cnt > 0) {
+ *dst32 = ((uint32_t)src->red >> (8 - pf->rbits)) << pf->rshift;
+ *dst32 |= ((uint32_t)src->green >> (8 - pf->gbits)) << pf->gshift;
+ *dst32 |= ((uint32_t)src->blue >> (8 - pf->bbits)) << pf->bshift;
+ *dst32 |= ((uint32_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
+ dst32++, src++, cnt--;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+/* PixelFormat -> PixelFormat conversions */
+
+static void convert_copy(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
+{
+ uint32_t bytes = cnt * conv->src.bytes_per_pixel;
+ memcpy(dst, src, bytes);
+}
+
+static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
+{
+ if (conv->conv_cnt < cnt) {
+ conv->conv_cnt = cnt;
+ conv->conv_buf = qemu_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt);
+ }
+ conv->conv_from(&conv->src, conv->conv_buf, src, cnt);
+ conv->conv_to(&conv->dst, dst, conv->conv_buf, cnt);
+}
+
+/* ----------------------------------------------------------------------- */
+/* public interface */
+
+QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src)
+{
+ QemuPfConv *conv = qemu_mallocz(sizeof(QemuPfConv));
+
+ conv->src = *src;
+ conv->dst = *dst;
+
+ if (memcmp(&conv->src, &conv->dst, sizeof(PixelFormat)) == 0) {
+ /* formats identical, can simply copy */
+ conv->convert = convert_copy;
+ } else {
+ /* generic two-step conversion: src -> QemuPixel -> dst */
+ switch (conv->src.bytes_per_pixel) {
+ case 2:
+ conv->conv_from = conv_16_to_pixel;
+ break;
+ case 4:
+ if (conv->src.rbits == 8 && conv->src.gbits == 8 && conv->src.bbits == 8) {
+ conv->conv_from = conv_32_to_pixel_fast;
+ } else {
+ conv->conv_from = conv_32_to_pixel_generic;
+ }
+ break;
+ default:
+ goto err;
+ }
+ switch (conv->dst.bytes_per_pixel) {
+ case 2:
+ conv->conv_to = conv_pixel_to_16;
+ break;
+ case 4:
+ conv->conv_to = conv_pixel_to_32;
+ break;
+ default:
+ goto err;
+ }
+ conv->convert = convert_generic;
+ }
+ return conv;
+
+err:
+ qemu_free(conv);
+ return NULL;
+}
+
+void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
+{
+ conv->convert(conv, dst, src, cnt);
+}
+
+void qemu_pf_conv_put(QemuPfConv *conv)
+{
+ if (conv) {
+ qemu_free(conv->conv_buf);
+ qemu_free(conv);
+ }
+}
diff --git a/pflib.h b/pflib.h
new file mode 100644
index 0000000..b70c313
--- /dev/null
+++ b/pflib.h
@@ -0,0 +1,20 @@
+#ifndef __QEMU_PFLIB_H
+#define __QEMU_PFLIB_H
+
+/*
+ * PixelFormat conversion library.
+ *
+ * Author: Gerd Hoffmann <kraxel at redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+typedef struct QemuPfConv QemuPfConv;
+
+QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src);
+void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt);
+void qemu_pf_conv_put(QemuPfConv *conv);
+
+#endif
commit 526c523781fd3684a1902322b1d67785eae15f5b
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Aug 25 12:19:49 2010 +0200
Use machine_init() to register virtfs config options.
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index ad69b0e..280b8f5 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -16,6 +16,7 @@
#include "qemu-queue.h"
#include "osdep.h"
#include "qemu-common.h"
+#include "qemu-config.h"
static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries =
QTAILQ_HEAD_INITIALIZER(fstype_entries);
@@ -75,3 +76,11 @@ FsTypeEntry *get_fsdev_fsentry(char *id)
}
return NULL;
}
+
+static void fsdev_register_config(void)
+{
+ qemu_add_opts(&qemu_fsdev_opts);
+ qemu_add_opts(&qemu_virtfs_opts);
+}
+machine_init(fsdev_register_config);
+
diff --git a/vl.c b/vl.c
index f434193..2edc853 100644
--- a/vl.c
+++ b/vl.c
@@ -1863,11 +1863,6 @@ int main(int argc, char **argv, char **envp)
tb_size = 0;
autostart= 1;
-#ifdef CONFIG_VIRTFS
- qemu_add_opts(&qemu_fsdev_opts);
- qemu_add_opts(&qemu_virtfs_opts);
-#endif
-
/* first pass of option parsing */
optind = 1;
while (optind < argc) {
commit 6b62dc2dd7d590815a3b7713633ce59ef64a17d4
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Aug 25 10:51:06 2010 +0200
Use display types for local display only.
This patch drops DT_VNC. The display types are only used to select
select the local display (i.e. curses, sdl, coca, ...). Remote
displays (for now only vnc, spice will follow) can be enabled
independently.
diff --git a/sysemu.h b/sysemu.h
index a1f6466..b81a70e 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -94,7 +94,6 @@ typedef enum DisplayType
DT_DEFAULT,
DT_CURSES,
DT_SDL,
- DT_VNC,
DT_NOGRAPHIC,
} DisplayType;
diff --git a/vl.c b/vl.c
index 3f45aa9..f434193 100644
--- a/vl.c
+++ b/vl.c
@@ -176,6 +176,7 @@ static const char *data_dir;
const char *bios_name = NULL;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
DisplayType display_type = DT_DEFAULT;
+int display_remote = 0;
const char* keyboard_layout = NULL;
ram_addr_t ram_size;
const char *mem_path = NULL;
@@ -2477,7 +2478,7 @@ int main(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_vnc:
- display_type = DT_VNC;
+ display_remote++;
vnc_display = optarg;
break;
case QEMU_OPTION_no_acpi:
@@ -2921,17 +2922,17 @@ int main(int argc, char **argv, char **envp)
/* just use the first displaystate for the moment */
ds = get_displaystate();
- if (display_type == DT_DEFAULT) {
+ if (display_type == DT_DEFAULT && !display_remote) {
#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
display_type = DT_SDL;
#else
- display_type = DT_VNC;
vnc_display = "localhost:0,to=99";
show_vnc_port = 1;
#endif
}
+ /* init local displays */
switch (display_type) {
case DT_NOGRAPHIC:
break;
@@ -2949,7 +2950,12 @@ int main(int argc, char **argv, char **envp)
cocoa_display_init(ds, full_screen);
break;
#endif
- case DT_VNC:
+ default:
+ break;
+ }
+
+ /* init remote displays */
+ if (vnc_display) {
vnc_display_init(ds);
if (vnc_display_open(ds, vnc_display) < 0)
exit(1);
@@ -2957,12 +2963,10 @@ int main(int argc, char **argv, char **envp)
if (show_vnc_port) {
printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
}
- break;
- default:
- break;
}
- dpy_resize(ds);
+ /* display setup */
+ dpy_resize(ds);
dcl = ds->listeners;
while (dcl != NULL) {
if (dcl->dpy_refresh != NULL) {
@@ -2972,12 +2976,10 @@ int main(int argc, char **argv, char **envp)
}
dcl = dcl->next;
}
-
- if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
+ if (ds->gui_timer == NULL) {
nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
}
-
text_consoles_set_display(ds);
if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
commit d9d334176c5dba23b47be07192f431b0c030928d
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date: Tue Sep 21 15:43:03 2010 +0100
blkverify: Add block driver for verifying I/O
The blkverify block driver makes investigating image format data
corruption much easier. A raw image initialized with the same contents
as the test image (e.g. qcow2 file) must be provided. The raw image
mirrors read/write operations and is used to verify that data read from
the test image is correct.
See docs/blkverify.txt for more information.
Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/Makefile.objs b/Makefile.objs
index 3ef6d80..dad4593 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -14,7 +14,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
-block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o
+block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
block-nested-$(CONFIG_WIN32) += raw-win32.o
block-nested-$(CONFIG_POSIX) += raw-posix.o
block-nested-$(CONFIG_CURL) += curl.o
diff --git a/block/blkverify.c b/block/blkverify.c
new file mode 100644
index 0000000..4202685
--- /dev/null
+++ b/block/blkverify.c
@@ -0,0 +1,382 @@
+/*
+ * Block protocol for block driver correctness testing
+ *
+ * Copyright (C) 2010 IBM, Corp.
+ *
+ * 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 <stdarg.h>
+#include "qemu_socket.h" /* for EINPROGRESS on Windows */
+#include "block_int.h"
+
+typedef struct {
+ BlockDriverState *test_file;
+} BDRVBlkverifyState;
+
+typedef struct BlkverifyAIOCB BlkverifyAIOCB;
+struct BlkverifyAIOCB {
+ BlockDriverAIOCB common;
+ QEMUBH *bh;
+
+ /* Request metadata */
+ bool is_write;
+ int64_t sector_num;
+ int nb_sectors;
+
+ int ret; /* first completed request's result */
+ unsigned int done; /* completion counter */
+ bool *finished; /* completion signal for cancel */
+
+ QEMUIOVector *qiov; /* user I/O vector */
+ QEMUIOVector raw_qiov; /* cloned I/O vector for raw file */
+ void *buf; /* buffer for raw file I/O */
+
+ void (*verify)(BlkverifyAIOCB *acb);
+};
+
+static void blkverify_aio_cancel(BlockDriverAIOCB *blockacb)
+{
+ BlkverifyAIOCB *acb = (BlkverifyAIOCB *)blockacb;
+ bool finished = false;
+
+ /* Wait until request completes, invokes its callback, and frees itself */
+ acb->finished = &finished;
+ while (!finished) {
+ qemu_aio_wait();
+ }
+}
+
+static AIOPool blkverify_aio_pool = {
+ .aiocb_size = sizeof(BlkverifyAIOCB),
+ .cancel = blkverify_aio_cancel,
+};
+
+static void blkverify_err(BlkverifyAIOCB *acb, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "blkverify: %s sector_num=%ld nb_sectors=%d ",
+ acb->is_write ? "write" : "read", acb->sector_num,
+ acb->nb_sectors);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(1);
+}
+
+/* Valid blkverify filenames look like blkverify:path/to/raw_image:path/to/image */
+static int blkverify_open(BlockDriverState *bs, const char *filename, int flags)
+{
+ BDRVBlkverifyState *s = bs->opaque;
+ int ret;
+ char *raw, *c;
+
+ /* Parse the blkverify: prefix */
+ if (strncmp(filename, "blkverify:", strlen("blkverify:"))) {
+ return -EINVAL;
+ }
+ filename += strlen("blkverify:");
+
+ /* Parse the raw image filename */
+ c = strchr(filename, ':');
+ if (c == NULL) {
+ return -EINVAL;
+ }
+
+ raw = strdup(filename);
+ raw[c - filename] = '\0';
+ ret = bdrv_file_open(&bs->file, raw, flags);
+ free(raw);
+ if (ret < 0) {
+ return ret;
+ }
+ filename = c + 1;
+
+ /* Open the test file */
+ s->test_file = bdrv_new("");
+ ret = bdrv_open(s->test_file, filename, flags, NULL);
+ if (ret < 0) {
+ bdrv_delete(s->test_file);
+ s->test_file = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static void blkverify_close(BlockDriverState *bs)
+{
+ BDRVBlkverifyState *s = bs->opaque;
+
+ bdrv_delete(s->test_file);
+ s->test_file = NULL;
+}
+
+static void blkverify_flush(BlockDriverState *bs)
+{
+ BDRVBlkverifyState *s = bs->opaque;
+
+ /* Only flush test file, the raw file is not important */
+ bdrv_flush(s->test_file);
+}
+
+static int64_t blkverify_getlength(BlockDriverState *bs)
+{
+ BDRVBlkverifyState *s = bs->opaque;
+
+ return bdrv_getlength(s->test_file);
+}
+
+/**
+ * Check that I/O vector contents are identical
+ *
+ * @a: I/O vector
+ * @b: I/O vector
+ * @ret: Offset to first mismatching byte or -1 if match
+ */
+static ssize_t blkverify_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
+{
+ int i;
+ ssize_t offset = 0;
+
+ assert(a->niov == b->niov);
+ for (i = 0; i < a->niov; i++) {
+ size_t len = 0;
+ uint8_t *p = (uint8_t *)a->iov[i].iov_base;
+ uint8_t *q = (uint8_t *)b->iov[i].iov_base;
+
+ assert(a->iov[i].iov_len == b->iov[i].iov_len);
+ while (len < a->iov[i].iov_len && *p++ == *q++) {
+ len++;
+ }
+
+ offset += len;
+
+ if (len != a->iov[i].iov_len) {
+ return offset;
+ }
+ }
+ return -1;
+}
+
+typedef struct {
+ int src_index;
+ struct iovec *src_iov;
+ void *dest_base;
+} IOVectorSortElem;
+
+static int sortelem_cmp_src_base(const void *a, const void *b)
+{
+ const IOVectorSortElem *elem_a = a;
+ const IOVectorSortElem *elem_b = b;
+
+ /* Don't overflow */
+ if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base) {
+ return -1;
+ } else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int sortelem_cmp_src_index(const void *a, const void *b)
+{
+ const IOVectorSortElem *elem_a = a;
+ const IOVectorSortElem *elem_b = b;
+
+ return elem_a->src_index - elem_b->src_index;
+}
+
+/**
+ * Copy contents of I/O vector
+ *
+ * The relative relationships of overlapping iovecs are preserved. This is
+ * necessary to ensure identical semantics in the cloned I/O vector.
+ */
+static void blkverify_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src,
+ void *buf)
+{
+ IOVectorSortElem sortelems[src->niov];
+ void *last_end;
+ int i;
+
+ /* Sort by source iovecs by base address */
+ for (i = 0; i < src->niov; i++) {
+ sortelems[i].src_index = i;
+ sortelems[i].src_iov = &src->iov[i];
+ }
+ qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_base);
+
+ /* Allocate buffer space taking into account overlapping iovecs */
+ last_end = NULL;
+ for (i = 0; i < src->niov; i++) {
+ struct iovec *cur = sortelems[i].src_iov;
+ ptrdiff_t rewind = 0;
+
+ /* Detect overlap */
+ if (last_end && last_end > cur->iov_base) {
+ rewind = last_end - cur->iov_base;
+ }
+
+ sortelems[i].dest_base = buf - rewind;
+ buf += cur->iov_len - MIN(rewind, cur->iov_len);
+ last_end = MAX(cur->iov_base + cur->iov_len, last_end);
+ }
+
+ /* Sort by source iovec index and build destination iovec */
+ qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_index);
+ for (i = 0; i < src->niov; i++) {
+ qemu_iovec_add(dest, sortelems[i].dest_base, src->iov[i].iov_len);
+ }
+}
+
+static BlkverifyAIOCB *blkverify_aio_get(BlockDriverState *bs, bool is_write,
+ int64_t sector_num, QEMUIOVector *qiov,
+ int nb_sectors,
+ BlockDriverCompletionFunc *cb,
+ void *opaque)
+{
+ BlkverifyAIOCB *acb = qemu_aio_get(&blkverify_aio_pool, bs, cb, opaque);
+
+ acb->bh = NULL;
+ acb->is_write = is_write;
+ acb->sector_num = sector_num;
+ acb->nb_sectors = nb_sectors;
+ acb->ret = -EINPROGRESS;
+ acb->done = 0;
+ acb->qiov = qiov;
+ acb->buf = NULL;
+ acb->verify = NULL;
+ acb->finished = NULL;
+ return acb;
+}
+
+static void blkverify_aio_bh(void *opaque)
+{
+ BlkverifyAIOCB *acb = opaque;
+
+ qemu_bh_delete(acb->bh);
+ if (acb->buf) {
+ qemu_iovec_destroy(&acb->raw_qiov);
+ qemu_vfree(acb->buf);
+ }
+ acb->common.cb(acb->common.opaque, acb->ret);
+ if (acb->finished) {
+ *acb->finished = true;
+ }
+ qemu_aio_release(acb);
+}
+
+static void blkverify_aio_cb(void *opaque, int ret)
+{
+ BlkverifyAIOCB *acb = opaque;
+
+ switch (++acb->done) {
+ case 1:
+ acb->ret = ret;
+ break;
+
+ case 2:
+ if (acb->ret != ret) {
+ blkverify_err(acb, "return value mismatch %d != %d", acb->ret, ret);
+ }
+
+ if (acb->verify) {
+ acb->verify(acb);
+ }
+
+ acb->bh = qemu_bh_new(blkverify_aio_bh, acb);
+ qemu_bh_schedule(acb->bh);
+ break;
+ }
+}
+
+static void blkverify_verify_readv(BlkverifyAIOCB *acb)
+{
+ ssize_t offset = blkverify_iovec_compare(acb->qiov, &acb->raw_qiov);
+ if (offset != -1) {
+ blkverify_err(acb, "contents mismatch in sector %ld",
+ acb->sector_num + (offset / BDRV_SECTOR_SIZE));
+ }
+}
+
+static BlockDriverAIOCB *blkverify_aio_readv(BlockDriverState *bs,
+ int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+ BDRVBlkverifyState *s = bs->opaque;
+ BlkverifyAIOCB *acb = blkverify_aio_get(bs, false, sector_num, qiov,
+ nb_sectors, cb, opaque);
+
+ acb->verify = blkverify_verify_readv;
+ acb->buf = qemu_blockalign(bs->file, qiov->size);
+ qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);
+ blkverify_iovec_clone(&acb->raw_qiov, qiov, acb->buf);
+
+ if (!bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors,
+ blkverify_aio_cb, acb)) {
+ blkverify_aio_cb(acb, -EIO);
+ }
+ if (!bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors,
+ blkverify_aio_cb, acb)) {
+ blkverify_aio_cb(acb, -EIO);
+ }
+ return &acb->common;
+}
+
+static BlockDriverAIOCB *blkverify_aio_writev(BlockDriverState *bs,
+ int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+ BDRVBlkverifyState *s = bs->opaque;
+ BlkverifyAIOCB *acb = blkverify_aio_get(bs, true, sector_num, qiov,
+ nb_sectors, cb, opaque);
+
+ if (!bdrv_aio_writev(s->test_file, sector_num, qiov, nb_sectors,
+ blkverify_aio_cb, acb)) {
+ blkverify_aio_cb(acb, -EIO);
+ }
+ if (!bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
+ blkverify_aio_cb, acb)) {
+ blkverify_aio_cb(acb, -EIO);
+ }
+ return &acb->common;
+}
+
+static BlockDriverAIOCB *blkverify_aio_flush(BlockDriverState *bs,
+ BlockDriverCompletionFunc *cb,
+ void *opaque)
+{
+ BDRVBlkverifyState *s = bs->opaque;
+
+ /* Only flush test file, the raw file is not important */
+ return bdrv_aio_flush(s->test_file, cb, opaque);
+}
+
+static BlockDriver bdrv_blkverify = {
+ .format_name = "blkverify",
+ .protocol_name = "blkverify",
+
+ .instance_size = sizeof(BDRVBlkverifyState),
+
+ .bdrv_getlength = blkverify_getlength,
+
+ .bdrv_file_open = blkverify_open,
+ .bdrv_close = blkverify_close,
+ .bdrv_flush = blkverify_flush,
+
+ .bdrv_aio_readv = blkverify_aio_readv,
+ .bdrv_aio_writev = blkverify_aio_writev,
+ .bdrv_aio_flush = blkverify_aio_flush,
+};
+
+static void bdrv_blkverify_init(void)
+{
+ bdrv_register(&bdrv_blkverify);
+}
+
+block_init(bdrv_blkverify_init);
diff --git a/docs/blkverify.txt b/docs/blkverify.txt
new file mode 100644
index 0000000..d556dc4
--- /dev/null
+++ b/docs/blkverify.txt
@@ -0,0 +1,69 @@
+= Block driver correctness testing with blkverify =
+
+== Introduction ==
+
+This document describes how to use the blkverify protocol to test that a block
+driver is operating correctly.
+
+It is difficult to test and debug block drivers against real guests. Often
+processes inside the guest will crash because corrupt sectors were read as part
+of the executable. Other times obscure errors are raised by a program inside
+the guest. These issues are extremely hard to trace back to bugs in the block
+driver.
+
+Blkverify solves this problem by catching data corruption inside QEMU the first
+time bad data is read and reporting the disk sector that is corrupted.
+
+== How it works ==
+
+The blkverify protocol has two child block devices, the "test" device and the
+"raw" device. Read/write operations are mirrored to both devices so their
+state should always be in sync.
+
+The "raw" device is a raw image, a flat file, that has identical starting
+contents to the "test" image. The idea is that the "raw" device will handle
+read/write operations correctly and not corrupt data. It can be used as a
+reference for comparison against the "test" device.
+
+After a mirrored read operation completes, blkverify will compare the data and
+raise an error if it is not identical. This makes it possible to catch the
+first instance where corrupt data is read.
+
+== Example ==
+
+Imagine raw.img has 0xcd repeated throughout its first sector:
+
+ $ ./qemu-io -c 'read -v 0 512' raw.img
+ 00000000: cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd ................
+ 00000010: cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd ................
+ [...]
+ 000001e0: cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd ................
+ 000001f0: cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd ................
+ read 512/512 bytes at offset 0
+ 512.000000 bytes, 1 ops; 0.0000 sec (97.656 MiB/sec and 200000.0000 ops/sec)
+
+And test.img is corrupt, its first sector is zeroed when it shouldn't be:
+
+ $ ./qemu-io -c 'read -v 0 512' test.img
+ 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ [...]
+ 000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ read 512/512 bytes at offset 0
+ 512.000000 bytes, 1 ops; 0.0000 sec (81.380 MiB/sec and 166666.6667 ops/sec)
+
+This error is caught by blkverify:
+
+ $ ./qemu-io -c 'read 0 512' blkverify:a.img:b.img
+ blkverify: read sector_num=0 nb_sectors=4 contents mismatch in sector 0
+
+A more realistic scenario is verifying the installation of a guest OS:
+
+ $ ./qemu-img create raw.img 16G
+ $ ./qemu-img create -f qcow2 test.qcow2 16G
+ $ x86_64-softmmu/qemu-system-x86_64 -cdrom debian.iso \
+ -drive file=blkverify:raw.img:test.qcow2
+
+If the installation is aborted when blkverify detects corruption, use qemu-io
+to explore the contents of the disk image at the sector in question.
commit a5e3d9ef4dcca9b709999a98f6b37b9506c93ad3
Author: Bernhard Kohl <bernhard.kohl at nsn.com>
Date: Mon Sep 6 16:58:44 2010 +0200
scsi_bus: fix length and xfer_mode for RESERVE and RELEASE commands
For the RESERVE and RELEASE commands the length must be zero
and xfer_mode must be SCSI_XFER_NONE.
Signed-off-by: Bernhard Kohl <bernhard.kohl at nsn.com>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 7aa0bcd..5a3fd4b 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -208,6 +208,8 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
case SEEK_6:
case WRITE_FILEMARKS:
case SPACE:
+ case RESERVE:
+ case RELEASE:
case ERASE:
case ALLOW_MEDIUM_REMOVAL:
case VERIFY:
@@ -319,7 +321,6 @@ static void scsi_req_xfer_mode(SCSIRequest *req)
case WRITE_BUFFER:
case FORMAT_UNIT:
case REASSIGN_BLOCKS:
- case RESERVE:
case SEARCH_EQUAL:
case SEARCH_HIGH:
case SEARCH_LOW:
commit f8b6d67251cfafed930d5f8be402fb0adac61299
Author: Bernhard Kohl <bernhard.kohl at nsn.com>
Date: Mon Sep 6 16:07:33 2010 +0200
scsi-generic: add missing reset handler
Ensure that pending requests of a SCSI generic device are purged on
system reset. This also avoids calling a NULL function in lsi53c895a.
The lsi code was recently changed to call the .qdev.reset function.
Signed-off-by: Bernhard Kohl <bernhard.kohl at nsn.com>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 9538027..7212091 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -455,15 +455,31 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
return (buf[9] << 16) | (buf[10] << 8) | buf[11];
}
-static void scsi_destroy(SCSIDevice *d)
+static void scsi_generic_purge_requests(SCSIGenericState *s)
{
- SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
SCSIGenericReq *r;
while (!QTAILQ_EMPTY(&s->qdev.requests)) {
r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
+ if (r->req.aiocb) {
+ bdrv_aio_cancel(r->req.aiocb);
+ }
scsi_remove_request(r);
}
+}
+
+static void scsi_generic_reset(DeviceState *dev)
+{
+ SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
+
+ scsi_generic_purge_requests(s);
+}
+
+static void scsi_destroy(SCSIDevice *d)
+{
+ SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
+
+ scsi_generic_purge_requests(s);
blockdev_mark_auto_del(s->qdev.conf.bs);
}
@@ -537,6 +553,7 @@ static SCSIDeviceInfo scsi_generic_info = {
.qdev.name = "scsi-generic",
.qdev.desc = "pass through generic scsi device (/dev/sg*)",
.qdev.size = sizeof(SCSIGenericState),
+ .qdev.reset = scsi_generic_reset,
.init = scsi_generic_initfn,
.destroy = scsi_destroy,
.send_command = scsi_send_command,
commit 6f5f060b736cedc2d962114d20805fdd2889513a
Author: Kevin Wolf <kwolf at redhat.com>
Date: Mon Sep 13 18:24:10 2010 +0200
qcow2: Avoid bounce buffers for AIO write requests
qcow2 used to use bounce buffers for any AIO requests. This does not only imply
unnecessary copying, but also unbounded allocations which should be avoided.
This patch removes bounce buffers from the normal AIO write path. Encrypted
images continue to use a bounce buffer, however with constant size.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/qcow2.c b/block/qcow2.c
index 4a688b4..ee3481b 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -331,15 +331,12 @@ typedef struct QCowAIOCB {
BlockDriverAIOCB common;
int64_t sector_num;
QEMUIOVector *qiov;
- uint8_t *buf;
- void *orig_buf;
int remaining_sectors;
int cur_nr_sectors; /* number of sectors in current iteration */
uint64_t bytes_done;
uint64_t cluster_offset;
uint8_t *cluster_data;
BlockDriverAIOCB *hd_aiocb;
- struct iovec hd_iov;
QEMUIOVector hd_qiov;
QEMUBH *bh;
QCowL2Meta l2meta;
@@ -530,14 +527,7 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
acb->sector_num = sector_num;
acb->qiov = qiov;
- if (!is_write) {
- qemu_iovec_init(&acb->hd_qiov, qiov->niov);
- } else if (qiov->niov == 1) {
- acb->buf = (uint8_t *)qiov->iov->iov_base;
- } else {
- acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
- qemu_iovec_to_buffer(qiov, acb->buf);
- }
+ qemu_iovec_init(&acb->hd_qiov, qiov->niov);
acb->bytes_done = 0;
acb->remaining_sectors = nb_sectors;
@@ -589,7 +579,6 @@ static void qcow_aio_write_cb(void *opaque, int ret)
BlockDriverState *bs = acb->common.bs;
BDRVQcowState *s = bs->opaque;
int index_in_cluster;
- const uint8_t *src_buf;
int n_end;
acb->hd_aiocb = NULL;
@@ -605,7 +594,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
acb->remaining_sectors -= acb->cur_nr_sectors;
acb->sector_num += acb->cur_nr_sectors;
- acb->buf += acb->cur_nr_sectors * 512;
+ acb->bytes_done += acb->cur_nr_sectors * 512;
if (acb->remaining_sectors == 0) {
/* request completed */
@@ -636,20 +625,27 @@ static void qcow_aio_write_cb(void *opaque, int ret)
assert((acb->cluster_offset & 511) == 0);
+ qemu_iovec_reset(&acb->hd_qiov);
+ qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+ acb->cur_nr_sectors * 512);
+
if (s->crypt_method) {
if (!acb->cluster_data) {
acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
s->cluster_size);
}
- qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
- acb->cur_nr_sectors, 1, &s->aes_encrypt_key);
- src_buf = acb->cluster_data;
- } else {
- src_buf = acb->buf;
+
+ assert(acb->hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+ qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data);
+
+ qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
+ acb->cluster_data, acb->cur_nr_sectors, 1, &s->aes_encrypt_key);
+
+ qemu_iovec_reset(&acb->hd_qiov);
+ qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+ acb->cur_nr_sectors * 512);
}
- acb->hd_iov.iov_base = (void *)src_buf;
- acb->hd_iov.iov_len = acb->cur_nr_sectors * 512;
- qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
acb->hd_aiocb = bdrv_aio_writev(bs->file,
(acb->cluster_offset >> 9) + index_in_cluster,
@@ -667,9 +663,8 @@ fail:
QLIST_REMOVE(&acb->l2meta, next_in_flight);
}
done:
- if (acb->qiov->niov > 1)
- qemu_vfree(acb->orig_buf);
acb->common.cb(acb->common.opaque, ret);
+ qemu_iovec_destroy(&acb->hd_qiov);
qemu_aio_release(acb);
}
commit bd28f835652e396841bb73080a07bcc08fe21bf0
Author: Kevin Wolf <kwolf at redhat.com>
Date: Mon Sep 13 18:08:52 2010 +0200
qcow2: Avoid bounce buffers for AIO read requests
qcow2 used to use bounce buffers for any AIO requests. This does not only imply
unnecessary copying, but also unbounded allocations which should be avoided.
This patch removes bounce buffers from the normal AIO read path, and constrains
them to a constant size for encrypted images.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index cb2e33f..fb4224a 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -350,6 +350,8 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
BDRVQcowState *s = bs->opaque;
int ret, index_in_cluster, n, n1;
uint64_t cluster_offset;
+ struct iovec iov;
+ QEMUIOVector qiov;
while (nb_sectors > 0) {
n = nb_sectors;
@@ -364,7 +366,11 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
if (!cluster_offset) {
if (bs->backing_hd) {
/* read from the base image */
- n1 = qcow2_backing_read1(bs->backing_hd, sector_num, buf, n);
+ iov.iov_base = buf;
+ iov.iov_len = n * 512;
+ qemu_iovec_init_external(&qiov, &iov, 1);
+
+ n1 = qcow2_backing_read1(bs->backing_hd, &qiov, sector_num, n);
if (n1 > 0) {
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING);
ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
diff --git a/block/qcow2.c b/block/qcow2.c
index a53014d..4a688b4 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -311,8 +311,8 @@ static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
}
/* handle reading after the end of the backing file */
-int qcow2_backing_read1(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors)
+int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
+ int64_t sector_num, int nb_sectors)
{
int n1;
if ((sector_num + nb_sectors) <= bs->total_sectors)
@@ -321,7 +321,9 @@ int qcow2_backing_read1(BlockDriverState *bs,
n1 = 0;
else
n1 = bs->total_sectors - sector_num;
- memset(buf + n1 * 512, 0, 512 * (nb_sectors - n1));
+
+ qemu_iovec_memset(qiov, 0, 512 * (nb_sectors - n1));
+
return n1;
}
@@ -333,6 +335,7 @@ typedef struct QCowAIOCB {
void *orig_buf;
int remaining_sectors;
int cur_nr_sectors; /* number of sectors in current iteration */
+ uint64_t bytes_done;
uint64_t cluster_offset;
uint8_t *cluster_data;
BlockDriverAIOCB *hd_aiocb;
@@ -397,15 +400,19 @@ static void qcow_aio_read_cb(void *opaque, int ret)
/* nothing to do */
} else {
if (s->crypt_method) {
- qcow2_encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
- acb->cur_nr_sectors, 0,
- &s->aes_decrypt_key);
+ qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
+ acb->cluster_data, acb->cur_nr_sectors, 0, &s->aes_decrypt_key);
+ qemu_iovec_reset(&acb->hd_qiov);
+ qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+ acb->cur_nr_sectors * 512);
+ qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data,
+ 512 * acb->cur_nr_sectors);
}
}
acb->remaining_sectors -= acb->cur_nr_sectors;
acb->sector_num += acb->cur_nr_sectors;
- acb->buf += acb->cur_nr_sectors * 512;
+ acb->bytes_done += acb->cur_nr_sectors * 512;
if (acb->remaining_sectors == 0) {
/* request completed */
@@ -415,6 +422,11 @@ static void qcow_aio_read_cb(void *opaque, int ret)
/* prepare next AIO request */
acb->cur_nr_sectors = acb->remaining_sectors;
+ if (s->crypt_method) {
+ acb->cur_nr_sectors = MIN(acb->cur_nr_sectors,
+ QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
+ }
+
ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
&acb->cur_nr_sectors, &acb->cluster_offset);
if (ret < 0) {
@@ -423,15 +435,17 @@ static void qcow_aio_read_cb(void *opaque, int ret)
index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
+ qemu_iovec_reset(&acb->hd_qiov);
+ qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+ acb->cur_nr_sectors * 512);
+
if (!acb->cluster_offset) {
+
if (bs->backing_hd) {
/* read from the base image */
- n1 = qcow2_backing_read1(bs->backing_hd, acb->sector_num,
- acb->buf, acb->cur_nr_sectors);
+ n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov,
+ acb->sector_num, acb->cur_nr_sectors);
if (n1 > 0) {
- acb->hd_iov.iov_base = (void *)acb->buf;
- acb->hd_iov.iov_len = acb->cur_nr_sectors * 512;
- qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num,
&acb->hd_qiov, acb->cur_nr_sectors,
@@ -445,7 +459,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
}
} else {
/* Note: in this case, no need to wait */
- memset(acb->buf, 0, 512 * acb->cur_nr_sectors);
+ qemu_iovec_memset(&acb->hd_qiov, 0, 512 * acb->cur_nr_sectors);
ret = qcow_schedule_bh(qcow_aio_read_bh, acb);
if (ret < 0)
goto done;
@@ -454,8 +468,11 @@ static void qcow_aio_read_cb(void *opaque, int ret)
/* add AIO support for compressed blocks ? */
if (qcow2_decompress_cluster(bs, acb->cluster_offset) < 0)
goto done;
- memcpy(acb->buf, s->cluster_cache + index_in_cluster * 512,
- 512 * acb->cur_nr_sectors);
+
+ qemu_iovec_from_buffer(&acb->hd_qiov,
+ s->cluster_cache + index_in_cluster * 512,
+ 512 * acb->cur_nr_sectors);
+
ret = qcow_schedule_bh(qcow_aio_read_bh, acb);
if (ret < 0)
goto done;
@@ -465,9 +482,23 @@ static void qcow_aio_read_cb(void *opaque, int ret)
goto done;
}
- acb->hd_iov.iov_base = (void *)acb->buf;
- acb->hd_iov.iov_len = acb->cur_nr_sectors * 512;
- qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+ if (s->crypt_method) {
+ /*
+ * For encrypted images, read everything into a temporary
+ * contiguous buffer on which the AES functions can work.
+ */
+ if (!acb->cluster_data) {
+ acb->cluster_data =
+ qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+ }
+
+ assert(acb->cur_nr_sectors <=
+ QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
+ qemu_iovec_reset(&acb->hd_qiov);
+ qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+ 512 * acb->cur_nr_sectors);
+ }
+
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
acb->hd_aiocb = bdrv_aio_readv(bs->file,
(acb->cluster_offset >> 9) + index_in_cluster,
@@ -481,11 +512,8 @@ static void qcow_aio_read_cb(void *opaque, int ret)
return;
done:
- if (acb->qiov->niov > 1) {
- qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
- qemu_vfree(acb->orig_buf);
- }
acb->common.cb(acb->common.opaque, ret);
+ qemu_iovec_destroy(&acb->hd_qiov);
qemu_aio_release(acb);
}
@@ -501,13 +529,17 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
acb->hd_aiocb = NULL;
acb->sector_num = sector_num;
acb->qiov = qiov;
- if (qiov->niov > 1) {
- acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
- if (is_write)
- qemu_iovec_to_buffer(qiov, acb->buf);
- } else {
+
+ if (!is_write) {
+ qemu_iovec_init(&acb->hd_qiov, qiov->niov);
+ } else if (qiov->niov == 1) {
acb->buf = (uint8_t *)qiov->iov->iov_base;
+ } else {
+ acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
+ qemu_iovec_to_buffer(qiov, acb->buf);
}
+
+ acb->bytes_done = 0;
acb->remaining_sectors = nb_sectors;
acb->cur_nr_sectors = 0;
acb->cluster_offset = 0;
diff --git a/block/qcow2.h b/block/qcow2.h
index 3ff162e..356a34a 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -166,8 +166,8 @@ static inline int64_t align_offset(int64_t offset, int n)
// FIXME Need qcow2_ prefix to global functions
/* qcow2.c functions */
-int qcow2_backing_read1(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors);
+int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
+ int64_t sector_num, int nb_sectors);
/* qcow2-refcount.c functions */
int qcow2_refcount_init(BlockDriverState *bs);
commit b8a83a4f79ca4cd0689117b119ffaa1a91b00d52
Author: Kevin Wolf <kwolf at redhat.com>
Date: Mon Sep 13 18:06:11 2010 +0200
cutils: qemu_iovec_copy and qemu_iovec_memset
This adds two functions that work on QEMUIOVectors and will be used by the next
qcow2 patches.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/cutils.c b/cutils.c
index 036ae3c..5883737 100644
--- a/cutils.c
+++ b/cutils.c
@@ -168,30 +168,50 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
}
/*
- * Copies iovecs from src to the end dst until src is completely copied or the
- * total size of the copied iovec reaches size. The size of the last copied
- * iovec is changed in order to fit the specified total size if it isn't a
- * perfect fit already.
+ * Copies iovecs from src to the end of dst. It starts copying after skipping
+ * the given number of bytes in src and copies until src is completely copied
+ * or the total size of the copied iovec reaches size.The size of the last
+ * copied iovec is changed in order to fit the specified total size if it isn't
+ * a perfect fit already.
*/
-void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size)
+void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
+ size_t size)
{
int i;
size_t done;
+ void *iov_base;
+ uint64_t iov_len;
assert(dst->nalloc != -1);
done = 0;
for (i = 0; (i < src->niov) && (done != size); i++) {
- if (done + src->iov[i].iov_len > size) {
- qemu_iovec_add(dst, src->iov[i].iov_base, size - done);
+ if (skip >= src->iov[i].iov_len) {
+ /* Skip the whole iov */
+ skip -= src->iov[i].iov_len;
+ continue;
+ } else {
+ /* Skip only part (or nothing) of the iov */
+ iov_base = (uint8_t*) src->iov[i].iov_base + skip;
+ iov_len = src->iov[i].iov_len - skip;
+ skip = 0;
+ }
+
+ if (done + iov_len > size) {
+ qemu_iovec_add(dst, iov_base, size - done);
break;
} else {
- qemu_iovec_add(dst, src->iov[i].iov_base, src->iov[i].iov_len);
+ qemu_iovec_add(dst, iov_base, iov_len);
}
- done += src->iov[i].iov_len;
+ done += iov_len;
}
}
+void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size)
+{
+ qemu_iovec_copy(dst, src, 0, size);
+}
+
void qemu_iovec_destroy(QEMUIOVector *qiov)
{
assert(qiov->nalloc != -1);
@@ -234,6 +254,18 @@ void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count)
}
}
+void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count)
+{
+ size_t n;
+ int i;
+
+ for (i = 0; i < qiov->niov && count; ++i) {
+ n = MIN(count, qiov->iov[i].iov_len);
+ memset(qiov->iov[i].iov_base, c, n);
+ count -= n;
+ }
+}
+
#ifndef _WIN32
/* Sets a specific flag */
int fcntl_setfl(int fd, int flag)
diff --git a/qemu-common.h b/qemu-common.h
index dfd3dc0..5544ffd 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -278,11 +278,14 @@ typedef struct QEMUIOVector {
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
+void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
+ size_t size);
void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size);
void qemu_iovec_destroy(QEMUIOVector *qiov);
void qemu_iovec_reset(QEMUIOVector *qiov);
void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf);
void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count);
+void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count);
struct Monitor;
typedef struct Monitor Monitor;
commit 1b2adf28030ee3a570ba3a22401d44da2b18fe01
Author: Christoph Hellwig <hch at lst.de>
Date: Sun Sep 12 23:44:00 2010 +0200
ide: propagate the required alignment
IDE is a bit ugly in this respect. For one it doesn't really keep track
of a sector size - most of the protocol is in units of 512 bytes, and we
assume 2048 bytes for CDROMs which is correct most of the time.
Second IDE allocates an I/O buffer long before we know if we're dealing
with a CDROM or not, so increase the alignment for the io_buffer
unconditionally.
Signed-off-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 1e466d1..06b6e14 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2645,6 +2645,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs,
if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
s->drive_kind = IDE_CD;
bdrv_set_change_cb(bs, cdrom_change_cb, s);
+ bs->buffer_alignment = 2048;
} else {
if (!bdrv_is_inserted(s->bs)) {
error_report("Device needs media, but drive is empty");
@@ -2679,7 +2680,8 @@ static void ide_init1(IDEBus *bus, int unit)
s->bus = bus;
s->unit = unit;
s->drive_serial = drive_serial++;
- s->io_buffer = qemu_blockalign(s->bs, IDE_DMA_BUF_SECTORS*512 + 4);
+ /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
+ s->io_buffer = qemu_memalign(2048, IDE_DMA_BUF_SECTORS*512 + 4);
s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
s->smart_selftest_data = qemu_blockalign(s->bs, 512);
s->sector_write_timer = qemu_new_timer(vm_clock,
commit 73fdb1e1956c6ac10e76882a2e8426d794e02bb2
Author: Christoph Hellwig <hch at lst.de>
Date: Sun Sep 12 23:43:50 2010 +0200
scsi-disk: propagate the required alignment
Signed-off-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index ee20e8f..9628b39 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1178,6 +1178,7 @@ static int scsi_disk_initfn(SCSIDevice *dev)
s->qdev.blocksize = s->qdev.conf.logical_block_size;
}
s->cluster_size = s->qdev.blocksize / 512;
+ s->bs->buffer_alignment = s->qdev.blocksize;
s->qdev.type = TYPE_DISK;
qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
commit 316a7af35029d52c971f5df044eb69901d6f16ff
Author: Christoph Hellwig <hch at lst.de>
Date: Sun Sep 12 23:43:39 2010 +0200
virtio-blk: propagate the required alignment
Signed-off-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index bd6bbe6..a1df26d 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -540,6 +540,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
virtio_blk_save, virtio_blk_load, s);
bdrv_set_removable(s->bs, 0);
+ s->bs->buffer_alignment = conf->logical_block_size;
return &s->vdev;
}
commit 9f8e668eb1826434f61a63ff260d6c8b466e483a
Author: Kevin Wolf <kwolf at redhat.com>
Date: Fri Sep 17 17:02:09 2010 +0200
qcow2: Get rid of additional sync on COW
We always have a sync for the refcount update when a new cluster is
allocated. If we move this past the COW, we can save an additional sync.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 818c0db..cb2e33f 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -415,7 +415,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
&s->aes_encrypt_key);
}
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
- ret = bdrv_write_sync(bs->file, (cluster_offset >> 9) + n_start,
+ ret = bdrv_write(bs->file, (cluster_offset >> 9) + n_start,
s->cluster_data, n);
if (ret < 0)
return ret;
@@ -714,6 +714,13 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
(i << s->cluster_bits)) | QCOW_OFLAG_COPIED);
}
+ /*
+ * Before we update the L2 table to actually point to the new cluster, we
+ * need to be sure that the refcounts have been increased and COW was
+ * handled.
+ */
+ bdrv_flush(bs->file);
+
ret = write_l2_entries(bs, l2_table, l2_offset, l2_index, m->nb_clusters);
if (ret < 0) {
qcow2_l2_cache_reset(bs);
@@ -865,7 +872,6 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
QLIST_REMOVE(m, next_in_flight);
return cluster_offset;
}
- bdrv_flush(bs->file);
/* save info needed for meta data update */
m->offset = offset;
commit 29216ed14f0bae35d1d9bb114a1aee7ee6837670
Author: Kevin Wolf <kwolf at redhat.com>
Date: Fri Sep 17 16:57:48 2010 +0200
qcow2: Move sync out of qcow2_alloc_clusters
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index f562b16..818c0db 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -60,6 +60,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
qemu_free(new_l1_table);
return new_l1_table_offset;
}
+ bdrv_flush(bs->file);
BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
for(i = 0; i < s->l1_size; i++)
@@ -243,6 +244,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
if (l2_offset < 0) {
return l2_offset;
}
+ bdrv_flush(bs->file);
/* allocate a new entry in the l2 cache */
@@ -863,6 +865,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
QLIST_REMOVE(m, next_in_flight);
return cluster_offset;
}
+ bdrv_flush(bs->file);
/* save info needed for meta data update */
m->offset = offset;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 4fc3f80..7082601 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -629,8 +629,6 @@ int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size)
return ret;
}
- bdrv_flush(bs->file);
-
return offset;
}
@@ -678,6 +676,8 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
goto redo;
}
}
+
+ bdrv_flush(bs->file);
return offset;
}
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 6228612..bbfcaaa 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -138,6 +138,7 @@ static int qcow_write_snapshots(BlockDriverState *bs)
snapshots_size = offset;
snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
+ bdrv_flush(bs->file);
offset = snapshots_offset;
if (offset < 0) {
return offset;
@@ -271,6 +272,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
if (l1_table_offset < 0) {
goto fail;
}
+ bdrv_flush(bs->file);
sn->l1_table_offset = l1_table_offset;
sn->l1_size = s->l1_size;
commit 1c4c28149fff77b8c983fdabe4e76bdc8cadd572
Author: Kevin Wolf <kwolf at redhat.com>
Date: Fri Sep 17 16:36:58 2010 +0200
qcow2: Move sync out of update_refcount
Note that the flush is omitted intentionally in qcow2_free_clusters. If
anything, we can leak clusters here if we lose the writes.
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 7dc75d1..4fc3f80 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -261,6 +261,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
goto fail_block;
}
+ bdrv_flush(bs->file);
+
/* Initialize the new refcount block only after updating its refcount,
* update_refcount uses the refcount cache itself */
memset(s->refcount_block_cache, 0, s->cluster_size);
@@ -551,8 +553,6 @@ fail:
dummy = update_refcount(bs, offset, cluster_offset - offset, -addend);
}
- bdrv_flush(bs->file);
-
return ret;
}
@@ -575,6 +575,8 @@ static int update_cluster_refcount(BlockDriverState *bs,
return ret;
}
+ bdrv_flush(bs->file);
+
return get_refcount(bs, cluster_index);
}
@@ -626,6 +628,9 @@ int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size)
if (ret < 0) {
return ret;
}
+
+ bdrv_flush(bs->file);
+
return offset;
}
@@ -803,6 +808,10 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if (ret < 0) {
goto fail;
}
+
+ /* TODO Flushing once for the whole function should
+ * be enough */
+ bdrv_flush(bs->file);
}
/* compressed clusters are never modified */
refcount = 2;
commit c01828fb518561235812d1035804e6efca31182a
Author: Kevin Wolf <kwolf at redhat.com>
Date: Fri Sep 17 16:31:03 2010 +0200
qcow2: Move sync out of write_refcount_block_entries
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 4c19e7e..7dc75d1 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -444,7 +444,7 @@ static int write_refcount_block_entries(BlockDriverState *bs,
size = (last_index - first_index) << REFCOUNT_SHIFT;
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART);
- ret = bdrv_pwrite_sync(bs->file,
+ ret = bdrv_pwrite(bs->file,
refcount_block_offset + (first_index << REFCOUNT_SHIFT),
&s->refcount_block_cache[first_index], size);
if (ret < 0) {
@@ -551,6 +551,8 @@ fail:
dummy = update_refcount(bs, offset, cluster_offset - offset, -addend);
}
+ bdrv_flush(bs->file);
+
return ret;
}
commit c2e2872bf49884d2b2382613891ce979e95c11ca
Author: Laurent Vivier <laurent at vivier.eu>
Date: Fri Sep 17 20:37:25 2010 +0200
nbd: correctly manage default port
block/nbd.c: use default port number when none is specified
qemu-nbd.c: use IANA-assigned port number: 10809
Signed-off-by: Laurent Vivier <laurent at vivier.eu>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/nbd.c b/block/nbd.c
index 5e9d6cb..c8dc763 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -95,8 +95,6 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
if (r == p) {
goto out;
}
- } else if (name == NULL) {
- goto out;
}
sock = tcp_socket_outgoing(hostname, port);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 923a3bf..99f1d22 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -44,7 +44,7 @@ static void usage(const char *name)
"Usage: %s [OPTIONS] FILE\n"
"QEMU Disk Network Block Device Server\n"
"\n"
-" -p, --port=PORT port to listen on (default `1024')\n"
+" -p, --port=PORT port to listen on (default `%d')\n"
" -o, --offset=OFFSET offset into the image\n"
" -b, --bind=IFACE interface to bind to (default `0.0.0.0')\n"
" -k, --socket=PATH path to the unix socket\n"
@@ -62,7 +62,7 @@ static void usage(const char *name)
" -V, --version output version information and exit\n"
"\n"
"Report bugs to <anthony at codemonkey.ws>\n"
- , name, "DEVICE");
+ , name, NBD_DEFAULT_PORT, "DEVICE");
}
static void version(const char *name)
@@ -188,7 +188,7 @@ int main(int argc, char **argv)
bool readonly = false;
bool disconnect = false;
const char *bindto = "0.0.0.0";
- int port = 1024;
+ int port = NBD_DEFAULT_PORT;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
off_t fd_size;
commit 5fe16888d33af7aca0d613d888c161af68c755c3
Author: Laurent Vivier <laurent at vivier.eu>
Date: Fri Sep 17 18:13:57 2010 +0200
Improve qemu-nbd performance by 4400 %
This patch allows to reduce the boot time from an NBD server from 225 seconds to
5 seconds (time between the "boot cd:0" and the kernel init) for the
following command lines:
./qemu-nbd -t ../ISO/debian-500-powerpc-netinst.iso
and
./ppc-softmmu/qemu-system-ppc -cdrom nbd:localhost:1024
This patch combines the reply header and payload send operation.
Signed-off-by: Laurent Vivier <laurent at vivier.eu>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/nbd.c b/nbd.c
index 011b50f..4bf2eb7 100644
--- a/nbd.c
+++ b/nbd.c
@@ -49,6 +49,7 @@
/* This is all part of the "official" NBD API */
+#define NBD_REPLY_SIZE (4 + 4 + 8)
#define NBD_REQUEST_MAGIC 0x25609513
#define NBD_REPLY_MAGIC 0x67446698
@@ -588,7 +589,7 @@ static int nbd_receive_request(int csock, struct nbd_request *request)
int nbd_receive_reply(int csock, struct nbd_reply *reply)
{
- uint8_t buf[4 + 4 + 8];
+ uint8_t buf[NBD_REPLY_SIZE];
uint32_t magic;
memset(buf, 0xAA, sizeof(buf));
@@ -655,9 +656,9 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
if (nbd_receive_request(csock, &request) == -1)
return -1;
- if (request.len > data_size) {
+ if (request.len + NBD_REPLY_SIZE > data_size) {
LOG("len (%u) is larger than max len (%u)",
- request.len, data_size);
+ request.len + NBD_REPLY_SIZE, data_size);
errno = EINVAL;
return -1;
}
@@ -687,7 +688,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
case NBD_CMD_READ:
TRACE("Request type is READ");
- if (bdrv_read(bs, (request.from + dev_offset) / 512, data,
+ if (bdrv_read(bs, (request.from + dev_offset) / 512,
+ data + NBD_REPLY_SIZE,
request.len / 512) == -1) {
LOG("reading from file failed");
errno = EINVAL;
@@ -697,12 +699,21 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
TRACE("Read %u byte(s)", request.len);
- if (nbd_send_reply(csock, &reply) == -1)
- return -1;
+ /* Reply
+ [ 0 .. 3] magic (NBD_REPLY_MAGIC)
+ [ 4 .. 7] error (0 == no error)
+ [ 7 .. 15] handle
+ */
+
+ cpu_to_be32w((uint32_t*)data, NBD_REPLY_MAGIC);
+ cpu_to_be32w((uint32_t*)(data + 4), reply.error);
+ cpu_to_be64w((uint64_t*)(data + 8), reply.handle);
TRACE("Sending data to client");
- if (write_sync(csock, data, request.len) != request.len) {
+ if (write_sync(csock, data,
+ request.len + NBD_REPLY_SIZE) !=
+ request.len + NBD_REPLY_SIZE) {
LOG("writing to socket failed");
errno = EINVAL;
return -1;
commit 581b9e29f36eec5de0779c3dbade980e4405d92e
Author: Christoph Hellwig <hch at lst.de>
Date: Sun Sep 12 23:43:21 2010 +0200
raw-posix: handle > 512 byte alignment correctly
Replace the hardcoded handling of 512 byte alignment with bs->buffer_alignment
to handle larger sector size devices correctly.
Note that we can not rely on it to be initialize in bdrv_open, so deal
with the worst case there.
Signed-off-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 813372a..a5cbb7e 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -97,12 +97,12 @@
#define FTYPE_CD 1
#define FTYPE_FD 2
-#define ALIGNED_BUFFER_SIZE (32 * 512)
-
/* if the FD is not accessed during that time (in ms), we try to
reopen it to see if the disk has been changed */
#define FD_OPEN_TIMEOUT 1000
+#define MAX_BLOCKSIZE 4096
+
typedef struct BDRVRawState {
int fd;
int type;
@@ -118,7 +118,8 @@ typedef struct BDRVRawState {
int use_aio;
void *aio_ctx;
#endif
- uint8_t* aligned_buf;
+ uint8_t *aligned_buf;
+ unsigned aligned_buf_size;
} BDRVRawState;
static int fd_open(BlockDriverState *bs);
@@ -161,7 +162,12 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
s->aligned_buf = NULL;
if ((bdrv_flags & BDRV_O_NOCACHE)) {
- s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE);
+ /*
+ * Allocate a buffer for read/modify/write cycles. Chose the size
+ * pessimistically as we don't know the block size yet.
+ */
+ s->aligned_buf_size = 32 * MAX_BLOCKSIZE;
+ s->aligned_buf = qemu_memalign(MAX_BLOCKSIZE, s->aligned_buf_size);
if (s->aligned_buf == NULL) {
goto out_close;
}
@@ -278,8 +284,9 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
}
/*
- * offset and count are in bytes, but must be multiples of 512 for files
- * opened with O_DIRECT. buf must be aligned to 512 bytes then.
+ * offset and count are in bytes, but must be multiples of the sector size
+ * for files opened with O_DIRECT. buf must be aligned to sector size bytes
+ * then.
*
* This function may be called without alignment if the caller ensures
* that O_DIRECT is not in effect.
@@ -316,24 +323,25 @@ static int raw_pread(BlockDriverState *bs, int64_t offset,
uint8_t *buf, int count)
{
BDRVRawState *s = bs->opaque;
+ unsigned sector_mask = bs->buffer_alignment - 1;
int size, ret, shift, sum;
sum = 0;
if (s->aligned_buf != NULL) {
- if (offset & 0x1ff) {
- /* align offset on a 512 bytes boundary */
+ if (offset & sector_mask) {
+ /* align offset on a sector size bytes boundary */
- shift = offset & 0x1ff;
- size = (shift + count + 0x1ff) & ~0x1ff;
- if (size > ALIGNED_BUFFER_SIZE)
- size = ALIGNED_BUFFER_SIZE;
+ shift = offset & sector_mask;
+ size = (shift + count + sector_mask) & ~sector_mask;
+ if (size > s->aligned_buf_size)
+ size = s->aligned_buf_size;
ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
if (ret < 0)
return ret;
- size = 512 - shift;
+ size = bs->buffer_alignment - shift;
if (size > count)
size = count;
memcpy(buf, s->aligned_buf + shift, size);
@@ -346,15 +354,15 @@ static int raw_pread(BlockDriverState *bs, int64_t offset,
if (count == 0)
return sum;
}
- if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
+ if (count & sector_mask || (uintptr_t) buf & sector_mask) {
/* read on aligned buffer */
while (count) {
- size = (count + 0x1ff) & ~0x1ff;
- if (size > ALIGNED_BUFFER_SIZE)
- size = ALIGNED_BUFFER_SIZE;
+ size = (count + sector_mask) & ~sector_mask;
+ if (size > s->aligned_buf_size)
+ size = s->aligned_buf_size;
ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
if (ret < 0) {
@@ -404,25 +412,28 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
const uint8_t *buf, int count)
{
BDRVRawState *s = bs->opaque;
+ unsigned sector_mask = bs->buffer_alignment - 1;
int size, ret, shift, sum;
sum = 0;
if (s->aligned_buf != NULL) {
- if (offset & 0x1ff) {
- /* align offset on a 512 bytes boundary */
- shift = offset & 0x1ff;
- ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
+ if (offset & sector_mask) {
+ /* align offset on a sector size bytes boundary */
+ shift = offset & sector_mask;
+ ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf,
+ bs->buffer_alignment);
if (ret < 0)
return ret;
- size = 512 - shift;
+ size = bs->buffer_alignment - shift;
if (size > count)
size = count;
memcpy(s->aligned_buf + shift, buf, size);
- ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
+ ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf,
+ bs->buffer_alignment);
if (ret < 0)
return ret;
@@ -434,12 +445,12 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
if (count == 0)
return sum;
}
- if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
+ if (count & sector_mask || (uintptr_t) buf & sector_mask) {
- while ((size = (count & ~0x1ff)) != 0) {
+ while ((size = (count & ~sector_mask)) != 0) {
- if (size > ALIGNED_BUFFER_SIZE)
- size = ALIGNED_BUFFER_SIZE;
+ if (size > s->aligned_buf_size)
+ size = s->aligned_buf_size;
memcpy(s->aligned_buf, buf, size);
@@ -452,14 +463,16 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
count -= ret;
sum += ret;
}
- /* here, count < 512 because (count & ~0x1ff) == 0 */
+ /* here, count < 512 because (count & ~sector_mask) == 0 */
if (count) {
- ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
+ ret = raw_pread_aligned(bs, offset, s->aligned_buf,
+ bs->buffer_alignment);
if (ret < 0)
return ret;
memcpy(s->aligned_buf, buf, count);
- ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
+ ret = raw_pwrite_aligned(bs, offset, s->aligned_buf,
+ bs->buffer_alignment);
if (ret < 0)
return ret;
if (count < ret)
@@ -487,12 +500,12 @@ static int raw_write(BlockDriverState *bs, int64_t sector_num,
/*
* Check if all memory in this vector is sector aligned.
*/
-static int qiov_is_aligned(QEMUIOVector *qiov)
+static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
{
int i;
for (i = 0; i < qiov->niov; i++) {
- if ((uintptr_t) qiov->iov[i].iov_base % BDRV_SECTOR_SIZE) {
+ if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
return 0;
}
}
@@ -515,7 +528,7 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
* driver that it needs to copy the buffer.
*/
if (s->aligned_buf) {
- if (!qiov_is_aligned(qiov)) {
+ if (!qiov_is_aligned(bs, qiov)) {
type |= QEMU_AIO_MISALIGNED;
#ifdef CONFIG_LINUX_AIO
} else if (s->use_aio) {
commit 72aef7318f54f0ec8c84c2bf2bb8edc5702d7dd0
Author: Christoph Hellwig <hch at lst.de>
Date: Sun Sep 12 23:42:56 2010 +0200
use qemu_blockalign consistently
Use qemu_blockalign for all allocations in the block layer. This allows
increasing the required alignment, which is need to support O_DIRECT on
devices with large block sizes.
Signed-off-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Kevin Wolf <kwolf at redhat.com>
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 1446ca6..ee20e8f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -70,14 +70,15 @@ struct SCSIDiskState
char *serial;
};
-static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
+static SCSIDiskReq *scsi_new_request(SCSIDiskState *s, uint32_t tag,
+ uint32_t lun)
{
SCSIRequest *req;
SCSIDiskReq *r;
- req = scsi_req_alloc(sizeof(SCSIDiskReq), d, tag, lun);
+ req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun);
r = DO_UPCAST(SCSIDiskReq, req, req);
- r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
+ r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
return r;
}
@@ -939,7 +940,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
}
/* ??? Tags are not unique for different luns. We only implement a
single lun, so this should not matter. */
- r = scsi_new_request(d, tag, lun);
+ r = scsi_new_request(s, tag, lun);
outbuf = (uint8_t *)r->iov.iov_base;
is_write = 0;
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
diff --git a/hw/sd.c b/hw/sd.c
index c928120..4bcf1c0 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -440,7 +440,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi)
SDState *sd;
sd = (SDState *) qemu_mallocz(sizeof(SDState));
- sd->buf = qemu_memalign(512, 512);
+ sd->buf = qemu_blockalign(bs, 512);
sd->spi = is_spi;
sd->enable = 1;
sd_reset(sd, bs);
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index 10f1f03..842f1a2 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -270,7 +270,7 @@ static ssize_t handle_aiocb_rw(struct qemu_paiocb *aiocb)
* Ok, we have to do it the hard way, copy all segments into
* a single aligned buffer.
*/
- buf = qemu_memalign(512, aiocb->aio_nbytes);
+ buf = qemu_blockalign(aiocb->common.bs, aiocb->aio_nbytes);
if (aiocb->aio_type & QEMU_AIO_WRITE) {
char *p = buf;
int i;
diff --git a/qemu-io.c b/qemu-io.c
index bd3bd16..b4e5cc8 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -61,7 +61,7 @@ static void *qemu_io_alloc(size_t len, int pattern)
if (misalign)
len += MISALIGN_OFFSET;
- buf = qemu_memalign(512, len);
+ buf = qemu_blockalign(bs, len);
memset(buf, pattern, len);
if (misalign)
buf += MISALIGN_OFFSET;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 91b569f..923a3bf 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -446,7 +446,7 @@ int main(int argc, char **argv)
max_fd = sharing_fds[0];
nb_fds++;
- data = qemu_memalign(512, NBD_BUFFER_SIZE);
+ data = qemu_blockalign(bs, NBD_BUFFER_SIZE);
if (data == NULL)
errx(EXIT_FAILURE, "Cannot allocate data buffer");
commit a655211ac6d379c5b0813761e5d11415780f41fd
Author: Kevin Wolf <mail at kevin-wolf.de>
Date: Fri Sep 10 12:27:04 2010 +0200
vvfat: Use cache=unsafe
The qcow file used for write support in vvfat is a temporary file,
so we can use cache=unsafe there. Without this, write support is just
too slow to be of any use.
Signed-off-by: Kevin Wolf <mail at kevin-wolf.de>
diff --git a/block/vvfat.c b/block/vvfat.c
index 0772037..53e57bf 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2788,6 +2788,7 @@ static int enable_write_target(BDRVVVFATState *s)
{
BlockDriver *bdrv_qcow;
QEMUOptionParameter *options;
+ int ret;
int size = sector2cluster(s, s->sector_count);
s->used_clusters = calloc(size, 1);
@@ -2803,11 +2804,16 @@ static int enable_write_target(BDRVVVFATState *s)
if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
return -1;
+
s->qcow = bdrv_new("");
- if (s->qcow == NULL ||
- bdrv_open(s->qcow, s->qcow_filename, BDRV_O_RDWR, bdrv_qcow) < 0)
- {
- return -1;
+ if (s->qcow == NULL) {
+ return -1;
+ }
+
+ ret = bdrv_open(s->qcow, s->qcow_filename,
+ BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow);
+ if (ret < 0) {
+ return ret;
}
#ifndef _WIN32
commit 9217e26f43df4aab7deaea35b21caacc1f1f854b
Author: Kevin Wolf <mail at kevin-wolf.de>
Date: Fri Sep 10 12:27:03 2010 +0200
vvfat: Fix double free for opening the image rw
Allocation and deallocation of bs->opaque is not in the control of a
block driver. Therefore it should not set bs->opaque to a data structure
used by another bs, or closing the image will lead to a double free.
Signed-off-by: Kevin Wolf <mail at kevin-wolf.de>
diff --git a/block/vvfat.c b/block/vvfat.c
index 5898d66..0772037 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2768,12 +2768,12 @@ static int vvfat_is_allocated(BlockDriverState *bs,
static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
const uint8_t* buffer, int nb_sectors) {
- BDRVVVFATState* s = bs->opaque;
+ BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
return try_commit(s);
}
static void write_target_close(BlockDriverState *bs) {
- BDRVVVFATState* s = bs->opaque;
+ BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
bdrv_delete(s->qcow);
free(s->qcow_filename);
}
@@ -2816,7 +2816,8 @@ static int enable_write_target(BDRVVVFATState *s)
s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
s->bs->backing_hd->drv = &vvfat_write_target;
- s->bs->backing_hd->opaque = s;
+ s->bs->backing_hd->opaque = qemu_malloc(sizeof(void*));
+ *(void**)s->bs->backing_hd->opaque = s;
return 0;
}
commit ac48e389d073bf2c8703745eef4824fabe0427ba
Author: Kevin Wolf <mail at kevin-wolf.de>
Date: Fri Sep 10 12:27:02 2010 +0200
vvfat: Fix segfault on write to read-only disk
vvfat tries to set the readonly flag in its open function, but nowadays
this is overwritted with the readonly=... command line option. Check in
bdrv_write if the vvfat was opened read-only and return an error in this
case.
Without this check, vvfat tries to access the qcow bs, which is NULL
without enabled write support.
Signed-off-by: Kevin Wolf <mail at kevin-wolf.de>
diff --git a/block/vvfat.c b/block/vvfat.c
index 365332a..5898d66 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2665,6 +2665,11 @@ static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
DLOG(checkpoint());
+ /* Check if we're operating in read-only mode */
+ if (s->qcow == NULL) {
+ return -EACCES;
+ }
+
vvfat_close_current_file(s);
/*
More information about the Spice-commits
mailing list