Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-2' into staging
vga: add secondary stdvga variant
# gpg: Signature made Mon 28 Apr 2014 10:11:44 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
* remotes/kraxel/tags/pull-vga-2:
add secondary-vga to display-vga test
add display-vga test
vga: add secondary stdvga variant
vga: allow non-global vmstate
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/.gitignore b/.gitignore
index de90463..8a52709 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,8 +18,8 @@
/*-darwin-user
/*-linux-user
/*-bsd-user
-libdis*
-libuser
+/libdis*
+/libuser
/linux-headers/asm
/qga/qapi-generated
/qapi-generated
@@ -49,19 +49,9 @@
/qemu-monitor.texi
/qmp-commands.txt
/vscclient
-/test-bitops
-/test-coroutine
-/test-int128
-/test-opts-visitor
-/test-qmp-input-visitor
-/test-qmp-output-visitor
-/test-string-input-visitor
-/test-string-output-visitor
-/test-visitor-serialization
/fsdev/virtfs-proxy-helper
/fsdev/virtfs-proxy-helper.1
/fsdev/virtfs-proxy-helper.pod
-/.gdbinit
*.a
*.aux
*.cp
@@ -90,12 +80,8 @@
*.pc
.libs
.sdk
-*.swp
-*.orig
-.pc
*.gcda
*.gcno
-patches
/pc-bios/bios-pq/status
/pc-bios/vgabios-pq/status
/pc-bios/optionrom/linuxboot.asm
diff --git a/MAINTAINERS b/MAINTAINERS
index c66946f..b287ef8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -674,6 +674,8 @@
F: block*
F: block/
F: hw/block/
+F: qemu-img*
+F: qemu-io*
T: git git://repo.or.cz/qemu/kevin.git block
T: git git://github.com/stefanha/qemu.git block
diff --git a/block.c b/block.c
index fc2edd3..4745712 100644
--- a/block.c
+++ b/block.c
@@ -864,7 +864,7 @@
node_name = qdict_get_try_str(options, "node-name");
bdrv_assign_node_name(bs, node_name, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return -EINVAL;
}
@@ -1068,14 +1068,14 @@
*/
int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
{
- char backing_filename[PATH_MAX];
- int back_flags, ret;
+ char *backing_filename = g_malloc0(PATH_MAX);
+ int back_flags, ret = 0;
BlockDriver *back_drv = NULL;
Error *local_err = NULL;
if (bs->backing_hd != NULL) {
QDECREF(options);
- return 0;
+ goto free_exit;
}
/* NULL means an empty set of options */
@@ -1088,10 +1088,9 @@
backing_filename[0] = '\0';
} else if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) {
QDECREF(options);
- return 0;
+ goto free_exit;
} else {
- bdrv_get_full_backing_filename(bs, backing_filename,
- sizeof(backing_filename));
+ bdrv_get_full_backing_filename(bs, backing_filename, PATH_MAX);
}
if (bs->backing_format[0] != '\0') {
@@ -1112,7 +1111,7 @@
error_setg(errp, "Could not open backing file: %s",
error_get_pretty(local_err));
error_free(local_err);
- return ret;
+ goto free_exit;
}
if (bs->backing_hd->file) {
@@ -1123,7 +1122,9 @@
/* Recalculate the BlockLimits with the backing file */
bdrv_refresh_limits(bs);
- return 0;
+free_exit:
+ g_free(backing_filename);
+ return ret;
}
/*
@@ -1180,8 +1181,7 @@
void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp)
{
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
- char tmp_filename[PATH_MAX + 1];
-
+ char *tmp_filename = g_malloc0(PATH_MAX + 1);
int64_t total_size;
BlockDriver *bdrv_qcow2;
QEMUOptionParameter *create_options;
@@ -1197,15 +1197,15 @@
total_size = bdrv_getlength(bs);
if (total_size < 0) {
error_setg_errno(errp, -total_size, "Could not get image size");
- return;
+ goto out;
}
total_size &= BDRV_SECTOR_MASK;
/* Create the temporary image */
- ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
+ ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not get temporary filename");
- return;
+ goto out;
}
bdrv_qcow2 = bdrv_find_format("qcow2");
@@ -1221,7 +1221,7 @@
"'%s': %s", tmp_filename,
error_get_pretty(local_err));
error_free(local_err);
- return;
+ goto out;
}
/* Prepare a new options QDict for the temporary file */
@@ -1238,10 +1238,13 @@
bs->open_flags & ~BDRV_O_SNAPSHOT, bdrv_qcow2, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
- return;
+ goto out;
}
bdrv_append(bs_snapshot, bs);
+
+out:
+ g_free(tmp_filename);
}
/*
diff --git a/block/commit.c b/block/commit.c
index acec4ac..5c09f44 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -194,7 +194,7 @@
if ((on_error == BLOCKDEV_ON_ERROR_STOP ||
on_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
!bdrv_iostatus_is_enabled(bs)) {
- error_set(errp, QERR_INVALID_PARAMETER_COMBINATION);
+ error_setg(errp, "Invalid parameter combination");
return;
}
diff --git a/block/iscsi.c b/block/iscsi.c
index a636ea4..a30202b 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1095,16 +1095,15 @@
*inq = scsi_datain_unmarshall(task);
if (*inq == NULL) {
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
- goto fail;
+ goto fail_with_err;
}
return task;
fail:
- if (!error_is_set(errp)) {
- error_setg(errp, "iSCSI: Inquiry command failed : %s",
- iscsi_get_error(iscsi));
- }
+ error_setg(errp, "iSCSI: Inquiry command failed : %s",
+ iscsi_get_error(iscsi));
+fail_with_err:
if (task != NULL) {
scsi_free_scsi_task(task);
}
diff --git a/block/mirror.c b/block/mirror.c
index 2618c37..36f4f8e 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -680,7 +680,7 @@
mirror_start_job(bs, base, speed, 0, 0,
on_error, on_error, cb, opaque, &local_err,
&commit_active_job_driver, false, base);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto error_restore_flags;
}
diff --git a/block/nbd.c b/block/nbd.c
index 5512423..613f258 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -175,7 +175,7 @@
InetSocketAddress *addr = NULL;
addr = inet_parse(host_spec, errp);
- if (error_is_set(errp)) {
+ if (!addr) {
goto out;
}
diff --git a/block/nfs.c b/block/nfs.c
index 98aa363..9fa831f 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -343,7 +343,7 @@
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return -EINVAL;
}
diff --git a/block/quorum.c b/block/quorum.c
index 7f580a8..ecec3a5 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -753,7 +753,7 @@
opts = qemu_opts_create(&quorum_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
ret = -EINVAL;
goto exit;
}
@@ -828,7 +828,7 @@
g_free(opened);
exit:
/* propagate error */
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
QDECREF(list);
diff --git a/blockdev.c b/blockdev.c
index 09826f1..7810e9f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1115,6 +1115,7 @@
static void internal_snapshot_prepare(BlkTransactionState *common,
Error **errp)
{
+ Error *local_err = NULL;
const char *device;
const char *name;
BlockDriverState *bs;
@@ -1163,8 +1164,10 @@
}
/* check whether a snapshot with name exist */
- ret = bdrv_snapshot_find_by_id_and_name(bs, NULL, name, &old_sn, errp);
- if (error_is_set(errp)) {
+ ret = bdrv_snapshot_find_by_id_and_name(bs, NULL, name, &old_sn,
+ &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
return;
} else if (ret) {
error_setg(errp,
@@ -1520,14 +1523,16 @@
return;
}
if (!bdrv_dev_has_removable_media(bs)) {
- error_set(errp, QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
+ error_setg(errp, "Device '%s' is not removable",
+ bdrv_get_device_name(bs));
return;
}
if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) {
bdrv_dev_eject_request(bs, force);
if (!force) {
- error_set(errp, QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
+ error_setg(errp, "Device '%s' is locked",
+ bdrv_get_device_name(bs));
return;
}
}
@@ -2219,7 +2224,8 @@
return;
}
if (job->paused && !force) {
- error_set(errp, QERR_BLOCK_JOB_PAUSED, device);
+ error_setg(errp, "The block job for device '%s' is currently paused",
+ device);
return;
}
diff --git a/blockjob.c b/blockjob.c
index b3ce14c..cd4784f 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -88,7 +88,7 @@
Error *local_err = NULL;
if (!job->driver->set_speed) {
- error_set(errp, QERR_NOT_SUPPORTED);
+ error_set(errp, QERR_UNSUPPORTED);
return;
}
job->driver->set_speed(job, speed, &local_err);
diff --git a/configure b/configure
index b08afc3..870c939 100755
--- a/configure
+++ b/configure
@@ -1087,7 +1087,10 @@
;;
--enable-quorum) quorum="yes"
;;
- *) echo "ERROR: unknown option $opt"; show_help="yes"
+ *)
+ echo "ERROR: unknown option $opt"
+ echo "Try '$0 --help' for more information"
+ exit 1
;;
esac
done
@@ -1230,6 +1233,7 @@
--with-sdlabi select preferred SDL ABI 1.2 or 2.0
--disable-gtk disable gtk UI
--enable-gtk enable gtk UI
+ --with-gtkabi select preferred GTK ABI 2.0 or 3.0
--disable-virtfs disable VirtFS
--enable-virtfs enable VirtFS
--disable-vnc disable VNC
@@ -1353,7 +1357,7 @@
NOTE: The object files are built at the place where configure is launched
EOF
-exit 1
+exit 0
fi
# Now we have handled --enable-tcg-interpreter and know we're not just
@@ -4346,6 +4350,7 @@
fi
if test "$sdl" = "yes" ; then
echo "CONFIG_SDL=y" >> $config_host_mak
+ echo "CONFIG_SDLABI=$sdlabi" >> $config_host_mak
echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak
fi
if test "$cocoa" = "yes" ; then
@@ -4429,6 +4434,7 @@
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
if test "$gtk" = "yes" ; then
echo "CONFIG_GTK=y" >> $config_host_mak
+ echo "CONFIG_GTKABI=$gtkabi" >> $config_host_mak
echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak
fi
if test "$vte" = "yes" ; then
diff --git a/cpus.c b/cpus.c
index 1104d61..7bbe153 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1454,7 +1454,7 @@
l = sizeof(buf);
if (l > size)
l = size;
- cpu_physical_memory_rw(addr, buf, l, 0);
+ cpu_physical_memory_read(addr, buf, l);
if (fwrite(buf, 1, l, f) != l) {
error_set(errp, QERR_IO_ERROR);
goto exit;
diff --git a/docs/writing-qmp-commands.txt b/docs/writing-qmp-commands.txt
index 8349dec..3930a9b 100644
--- a/docs/writing-qmp-commands.txt
+++ b/docs/writing-qmp-commands.txt
@@ -311,7 +311,7 @@
Error *errp = NULL;
qmp_hello_world(!!message, message, &errp);
- if (error_is_set(&errp)) {
+ if (errp) {
monitor_printf(mon, "%s\n", error_get_pretty(errp));
error_free(errp);
return;
@@ -483,7 +483,7 @@
Error *errp = NULL;
clock = qmp_query_alarm_clock(&errp);
- if (error_is_set(&errp)) {
+ if (errp) {
monitor_printf(mon, "Could not query alarm clock information\n");
error_free(errp);
return;
@@ -634,7 +634,7 @@
Error *errp = NULL;
method_list = qmp_query_alarm_methods(&errp);
- if (error_is_set(&errp)) {
+ if (errp) {
monitor_printf(mon, "Could not query alarm methods\n");
error_free(errp);
return;
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index bfecb87..cd291d3 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -760,6 +760,7 @@
return -1;
}
+ size = sizeof(qemu);
client = accept(sock, (struct sockaddr *)&qemu, &size);
if (client < 0) {
do_perror("accept");
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..8971f1b 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -176,7 +176,7 @@
{
.name = "drive_del",
- .args_type = "id:s",
+ .args_type = "id:B",
.params = "device",
.help = "remove host block device",
.user_print = monitor_user_noop,
@@ -658,6 +658,7 @@
.help = "add device, like -device on the command line",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_device_add,
+ .command_completion = device_add_completion,
},
STEXI
@@ -673,6 +674,7 @@
.params = "device",
.help = "remove device",
.mhandler.cmd = hmp_device_del,
+ .command_completion = device_del_completion,
},
STEXI
@@ -998,26 +1000,34 @@
{
.name = "dump-guest-memory",
- .args_type = "paging:-p,filename:F,begin:i?,length:i?",
- .params = "[-p] filename [begin] [length]",
- .help = "dump guest memory to file"
- "\n\t\t\t begin(optional): the starting physical address"
- "\n\t\t\t length(optional): the memory size, in bytes",
+ .args_type = "paging:-p,zlib:-z,lzo:-l,snappy:-s,filename:F,begin:i?,length:i?",
+ .params = "[-p] [-z|-l|-s] filename [begin length]",
+ .help = "dump guest memory into file 'filename'.\n\t\t\t"
+ "-p: do paging to get guest's memory mapping.\n\t\t\t"
+ "-z: dump in kdump-compressed format, with zlib compression.\n\t\t\t"
+ "-l: dump in kdump-compressed format, with lzo compression.\n\t\t\t"
+ "-s: dump in kdump-compressed format, with snappy compression.\n\t\t\t"
+ "begin: the starting physical address.\n\t\t\t"
+ "length: the memory size, in bytes.",
.mhandler.cmd = hmp_dump_guest_memory,
},
STEXI
-@item dump-guest-memory [-p] @var{protocol} @var{begin} @var{length}
+@item dump-guest-memory [-p] @var{filename} @var{begin} @var{length}
+@item dump-guest-memory [-z|-l|-s] @var{filename}
@findex dump-guest-memory
Dump guest memory to @var{protocol}. The file can be processed with crash or
-gdb.
- filename: dump file name
- paging: do paging to get guest's memory mapping
+gdb. Without -z|-l|-s, the dump format is ELF.
+ -p: do paging to get guest's memory mapping.
+ -z: dump in kdump-compressed format, with zlib compression.
+ -l: dump in kdump-compressed format, with lzo compression.
+ -s: dump in kdump-compressed format, with snappy compression.
+ filename: dump file name.
begin: the starting physical address. It's optional, and should be
- specified with length together.
+ specified together with length.
length: the memory size, in bytes. It's optional, and should be specified
- with begin together.
+ together with begin.
ETEXI
{
@@ -1254,6 +1264,7 @@
.params = "[qom-type=]type,id=str[,prop=value][,...]",
.help = "create QOM object",
.mhandler.cmd = hmp_object_add,
+ .command_completion = object_add_completion,
},
STEXI
@@ -1268,6 +1279,7 @@
.params = "id",
.help = "destroy QOM object",
.mhandler.cmd = hmp_object_del,
+ .command_completion = object_del_completion,
},
STEXI
diff --git a/hmp.c b/hmp.c
index 2f279c4..ca869ba 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1308,16 +1308,35 @@
{
Error *errp = NULL;
int paging = qdict_get_try_bool(qdict, "paging", 0);
+ int zlib = qdict_get_try_bool(qdict, "zlib", 0);
+ int lzo = qdict_get_try_bool(qdict, "lzo", 0);
+ int snappy = qdict_get_try_bool(qdict, "snappy", 0);
const char *file = qdict_get_str(qdict, "filename");
bool has_begin = qdict_haskey(qdict, "begin");
bool has_length = qdict_haskey(qdict, "length");
- /* kdump-compressed format is not supported for HMP */
- bool has_format = false;
int64_t begin = 0;
int64_t length = 0;
enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
char *prot;
+ if (zlib + lzo + snappy > 1) {
+ error_setg(&errp, "only one of '-z|-l|-s' can be set");
+ hmp_handle_error(mon, &errp);
+ return;
+ }
+
+ if (zlib) {
+ dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
+ }
+
+ if (lzo) {
+ dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
+ }
+
+ if (snappy) {
+ dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
+ }
+
if (has_begin) {
begin = qdict_get_int(qdict, "begin");
}
@@ -1328,7 +1347,7 @@
prot = g_strconcat("file:", file, NULL);
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
- has_format, dump_format, &errp);
+ true, dump_format, &errp);
hmp_handle_error(mon, &errp);
g_free(prot);
}
diff --git a/hmp.h b/hmp.h
index ed58f0e..20ef454 100644
--- a/hmp.h
+++ b/hmp.h
@@ -15,6 +15,7 @@
#define HMP_H
#include "qemu-common.h"
+#include "qemu/readline.h"
#include "qapi-types.h"
#include "qapi/qmp/qdict.h"
@@ -92,5 +93,9 @@
void hmp_cpu_add(Monitor *mon, const QDict *qdict);
void hmp_object_add(Monitor *mon, const QDict *qdict);
void hmp_object_del(Monitor *mon, const QDict *qdict);
+void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
#endif
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 83e4e93..9aa6725 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -987,8 +987,9 @@
*/
if (!s->migration_blocker) {
s->root_fid = fid;
- error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
- s->ctx.fs_root ? s->ctx.fs_root : "NULL", s->tag);
+ error_setg(&s->migration_blocker,
+ "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'",
+ s->ctx.fs_root ? s->ctx.fs_root : "NULL", s->tag);
migrate_add_blocker(s->migration_blocker);
}
out:
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index a67ca91..48c6ead 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -261,6 +261,9 @@
left = left * 255 / QEMU_HDA_AMP_STEPS;
right = right * 255 / QEMU_HDA_AMP_STEPS;
+ if (!st->state->mixer) {
+ return;
+ }
if (st->output) {
AUD_set_volume_out(st->voice.out, muted, left, right);
} else {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index c67acf5..585a8e9 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -587,8 +587,9 @@
/* We rely on power-of-2 blocksizes for bitmasks */
if ((value & (value - 1)) != 0) {
- error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
- dev->id?:"", name, (int64_t)value);
+ error_setg(errp,
+ "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
+ dev->id ?: "", name, (int64_t)value);
return;
}
@@ -853,7 +854,7 @@
{
switch (ret) {
case -EEXIST:
- error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
+ error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
object_get_typename(OBJECT(dev)), prop->name, value);
break;
default:
@@ -862,7 +863,7 @@
object_get_typename(OBJECT(dev)), prop->name, value);
break;
case -ENOENT:
- error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
+ error_setg(errp, "Property '%s.%s' can't find value '%s'",
object_get_typename(OBJECT(dev)), prop->name, value);
break;
case 0:
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index a1c3d1c..a967b48 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -124,14 +124,14 @@
static void read_guest_rom_state(VAPICROMState *s)
{
- cpu_physical_memory_rw(s->rom_state_paddr, (void *)&s->rom_state,
- sizeof(GuestROMState), 0);
+ cpu_physical_memory_read(s->rom_state_paddr, &s->rom_state,
+ sizeof(GuestROMState));
}
static void write_guest_rom_state(VAPICROMState *s)
{
- cpu_physical_memory_rw(s->rom_state_paddr, (void *)&s->rom_state,
- sizeof(GuestROMState), 1);
+ cpu_physical_memory_write(s->rom_state_paddr, &s->rom_state,
+ sizeof(GuestROMState));
}
static void update_guest_rom_state(VAPICROMState *s)
@@ -311,16 +311,14 @@
for (pos = le32_to_cpu(s->rom_state.fixup_start);
pos < le32_to_cpu(s->rom_state.fixup_end);
pos += 4) {
- cpu_physical_memory_rw(paddr + pos - s->rom_state.vaddr,
- (void *)&offset, sizeof(offset), 0);
+ cpu_physical_memory_read(paddr + pos - s->rom_state.vaddr,
+ &offset, sizeof(offset));
offset = le32_to_cpu(offset);
- cpu_physical_memory_rw(paddr + offset, (void *)&patch,
- sizeof(patch), 0);
+ cpu_physical_memory_read(paddr + offset, &patch, sizeof(patch));
patch = le32_to_cpu(patch);
patch += rom_state_vaddr - le32_to_cpu(s->rom_state.vaddr);
patch = cpu_to_le32(patch);
- cpu_physical_memory_rw(paddr + offset, (void *)&patch,
- sizeof(patch), 1);
+ cpu_physical_memory_write(paddr + offset, &patch, sizeof(patch));
}
read_guest_rom_state(s);
s->vapic_paddr = paddr + le32_to_cpu(s->rom_state.vapic_vaddr) -
@@ -364,8 +362,8 @@
}
vapic_paddr = s->vapic_paddr +
(((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
- cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
- (void *)&enabled, sizeof(enabled), 1);
+ cpu_physical_memory_write(vapic_paddr + offsetof(VAPICState, enabled),
+ &enabled, sizeof(enabled));
apic_enable_vapic(cpu->apic_state, vapic_paddr);
s->state = VAPIC_ACTIVE;
@@ -535,7 +533,7 @@
uint8_t *rom;
rom = g_malloc(s->rom_size);
- cpu_physical_memory_rw(rom_paddr, rom, s->rom_size, 0);
+ cpu_physical_memory_read(rom_paddr, rom, s->rom_size);
for (pos = 0; pos < s->rom_size - sizeof(vmcall_pattern); pos++) {
if (kvm_irqchip_in_kernel()) {
@@ -551,8 +549,7 @@
}
if (memcmp(rom + pos, pattern, 7) == 0 &&
(rom[pos + 7] == alternates[0] || rom[pos + 7] == alternates[1])) {
- cpu_physical_memory_rw(rom_paddr + pos + 5, (uint8_t *)patch,
- 3, 1);
+ cpu_physical_memory_write(rom_paddr + pos + 5, patch, 3);
/*
* Don't flush the tb here. Under ordinary conditions, the patched
* calls are miles away from the current IP. Under malicious
@@ -760,8 +757,8 @@
run_on_cpu(first_cpu, do_vapic_enable, s);
} else {
zero = g_malloc0(s->rom_state.vapic_size);
- cpu_physical_memory_rw(s->vapic_paddr, zero,
- s->rom_state.vapic_size, 1);
+ cpu_physical_memory_write(s->vapic_paddr, zero,
+ s->rom_state.vapic_size);
g_free(zero);
}
}
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index b8c061b..2f40cba 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -98,8 +98,8 @@
return;
}
if (sync_type & SYNC_FROM_VAPIC) {
- cpu_physical_memory_rw(s->vapic_paddr, (void *)&vapic_state,
- sizeof(vapic_state), 0);
+ cpu_physical_memory_read(s->vapic_paddr, &vapic_state,
+ sizeof(vapic_state));
s->tpr = vapic_state.tpr;
}
if (sync_type & (SYNC_TO_VAPIC | SYNC_ISR_IRR_TO_VAPIC)) {
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 8d144ba..768e528 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -684,8 +684,8 @@
}
if (s->role_val == IVSHMEM_PEER) {
- error_set(&s->migration_blocker, QERR_DEVICE_FEATURE_BLOCKS_MIGRATION,
- "peer mode", "ivshmem");
+ error_setg(&s->migration_blocker,
+ "Migration is disabled when using feature 'peer mode' in device 'ivshmem'");
migrate_add_blocker(s->migration_blocker);
}
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 7cb47b3..ebe5057 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -718,7 +718,6 @@
s->csr[94] = 0x0000;
s->csr[100] = 0x0200;
s->csr[103] = 0x0105;
- s->csr[103] = 0x0105;
s->csr[112] = 0x0000;
s->csr[114] = 0x0000;
s->csr[122] = 0x0000;
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 839d97c..dbeb3c9 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -98,7 +98,7 @@
r |= 1;
break;
case 17:
- /* Marvel PHY on many xilinx boards. */
+ /* Marvell PHY on many xilinx boards. */
r = 0x8000; /* 1000Mb */
break;
case 18:
@@ -142,6 +142,9 @@
phy->regs[regnum] = data;
break;
}
+
+ /* Unconditionally clear regs[BMCR][BMCR_RESET] */
+ phy->regs[0] &= ~0x8000;
}
static void
diff --git a/include/exec/def-helper.h b/include/exec/def-helper.h
index 73d51f9..255b58b 100644
--- a/include/exec/def-helper.h
+++ b/include/exec/def-helper.h
@@ -84,7 +84,7 @@
#define dh_is_64bit_noreturn 0
#define dh_is_64bit_i32 0
#define dh_is_64bit_i64 1
-#define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
+#define dh_is_64bit_ptr (sizeof(void *) == 8)
#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
#define dh_is_signed_void 0
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index a49ea11..42d8671 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -79,7 +79,6 @@
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);
int monitor_set_cpu(int cpu_index);
int monitor_get_cpu_index(void);
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index da75abf..902d1a7 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -12,7 +12,6 @@
#ifndef QERROR_H
#define QERROR_H
-#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
@@ -35,51 +34,30 @@
* Please keep the definitions in alphabetical order.
* Use scripts/check-qerror.sh to check.
*/
-#define QERR_ADD_CLIENT_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Could not add client"
-
-#define QERR_AMBIGUOUS_PATH \
- ERROR_CLASS_GENERIC_ERROR, "Path '%s' does not uniquely identify an object"
-
-#define QERR_BAD_BUS_FOR_DEVICE \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' can't go on a %s bus"
-
#define QERR_BASE_NOT_FOUND \
ERROR_CLASS_GENERIC_ERROR, "Base '%s' not found"
#define QERR_BLOCK_JOB_NOT_ACTIVE \
ERROR_CLASS_DEVICE_NOT_ACTIVE, "No active block job on device '%s'"
-#define QERR_BLOCK_JOB_PAUSED \
- ERROR_CLASS_GENERIC_ERROR, "The block job for device '%s' is currently paused"
-
#define QERR_BLOCK_JOB_NOT_READY \
ERROR_CLASS_GENERIC_ERROR, "The active block job for device '%s' cannot be completed"
#define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \
ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by device '%s' does not support feature '%s'"
-#define QERR_BUFFER_OVERRUN \
- ERROR_CLASS_GENERIC_ERROR, "An internal buffer overran"
-
#define QERR_BUS_NO_HOTPLUG \
ERROR_CLASS_GENERIC_ERROR, "Bus '%s' does not support hotplugging"
#define QERR_BUS_NOT_FOUND \
ERROR_CLASS_GENERIC_ERROR, "Bus '%s' not found"
-#define QERR_COMMAND_DISABLED \
- ERROR_CLASS_GENERIC_ERROR, "The command %s has been disabled for this instance"
-
#define QERR_COMMAND_NOT_FOUND \
ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found"
#define QERR_DEVICE_ENCRYPTED \
ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted"
-#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \
- ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when using feature '%s' in device '%s'"
-
#define QERR_DEVICE_HAS_NO_MEDIUM \
ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no medium"
@@ -92,15 +70,6 @@
#define QERR_DEVICE_IS_READ_ONLY \
ERROR_CLASS_GENERIC_ERROR, "Device '%s' is read only"
-#define QERR_DEVICE_LOCKED \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' is locked"
-
-#define QERR_DEVICE_MULTIPLE_BUSSES \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' has multiple child busses"
-
-#define QERR_DEVICE_NO_BUS \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no child bus"
-
#define QERR_DEVICE_NO_HOTPLUG \
ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging"
@@ -113,12 +82,6 @@
#define QERR_DEVICE_NOT_FOUND \
ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found"
-#define QERR_DEVICE_NOT_REMOVABLE \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not removable"
-
-#define QERR_DUPLICATE_ID \
- ERROR_CLASS_GENERIC_ERROR, "Duplicate ID '%s' for %s"
-
#define QERR_FD_NOT_FOUND \
ERROR_CLASS_GENERIC_ERROR, "File descriptor named '%s' not found"
@@ -131,15 +94,9 @@
#define QERR_INVALID_BLOCK_FORMAT \
ERROR_CLASS_GENERIC_ERROR, "Invalid block format '%s'"
-#define QERR_INVALID_OPTION_GROUP \
- ERROR_CLASS_GENERIC_ERROR, "There is no option group '%s'"
-
#define QERR_INVALID_PARAMETER \
ERROR_CLASS_GENERIC_ERROR, "Invalid parameter '%s'"
-#define QERR_INVALID_PARAMETER_COMBINATION \
- ERROR_CLASS_GENERIC_ERROR, "Invalid parameter combination"
-
#define QERR_INVALID_PARAMETER_TYPE \
ERROR_CLASS_GENERIC_ERROR, "Invalid parameter type for '%s', expected: %s"
@@ -152,9 +109,6 @@
#define QERR_IO_ERROR \
ERROR_CLASS_GENERIC_ERROR, "An IO error has occurred"
-#define QERR_JSON_PARSE_ERROR \
- ERROR_CLASS_GENERIC_ERROR, "JSON parse error, %s"
-
#define QERR_JSON_PARSING \
ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
@@ -164,45 +118,21 @@
#define QERR_MIGRATION_ACTIVE \
ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
-#define QERR_MIGRATION_NOT_SUPPORTED \
- ERROR_CLASS_GENERIC_ERROR, "State blocked by non-migratable device '%s'"
-
#define QERR_MISSING_PARAMETER \
ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' is missing"
-#define QERR_NO_BUS_FOR_DEVICE \
- ERROR_CLASS_GENERIC_ERROR, "No '%s' bus found for device '%s'"
-
-#define QERR_NOT_SUPPORTED \
- ERROR_CLASS_GENERIC_ERROR, "Not supported"
-
#define QERR_PERMISSION_DENIED \
ERROR_CLASS_GENERIC_ERROR, "Insufficient permission to perform this operation"
-#define QERR_PROPERTY_NOT_FOUND \
- ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' not found"
-
#define QERR_PROPERTY_VALUE_BAD \
ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' doesn't take value '%s'"
-#define QERR_PROPERTY_VALUE_IN_USE \
- ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't take value '%s', it's in use"
-
-#define QERR_PROPERTY_VALUE_NOT_FOUND \
- ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't find value '%s'"
-
-#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \
- ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2"
-
#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
#define QERR_QGA_COMMAND_FAILED \
ERROR_CLASS_GENERIC_ERROR, "Guest agent command failed, error was '%s'"
-#define QERR_QGA_LOGGING_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Guest agent failed to log non-optional log statement"
-
#define QERR_QMP_BAD_INPUT_OBJECT \
ERROR_CLASS_GENERIC_ERROR, "Expected '%s' in QMP input"
@@ -212,15 +142,9 @@
#define QERR_QMP_EXTRA_MEMBER \
ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' is unexpected"
-#define QERR_RESET_REQUIRED \
- ERROR_CLASS_GENERIC_ERROR, "Resetting the Virtual Machine is required"
-
#define QERR_SET_PASSWD_FAILED \
ERROR_CLASS_GENERIC_ERROR, "Could not set password"
-#define QERR_TOO_MANY_FILES \
- ERROR_CLASS_GENERIC_ERROR, "Too many open files"
-
#define QERR_UNDEFINED_ERROR \
ERROR_CLASS_GENERIC_ERROR, "An undefined error has occurred"
@@ -230,9 +154,6 @@
#define QERR_UNSUPPORTED \
ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported"
-#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
- ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'"
-
#define QERR_SOCKET_CONNECT_FAILED \
ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket"
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index dbd97c4..d4ba20e 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -8,6 +8,8 @@
QemuOptsList *qemu_find_opts(const char *group);
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
+QemuOpts *qemu_find_opts_singleton(const char *group);
+
void qemu_add_opts(QemuOptsList *list);
void qemu_add_drive_opts(QemuOptsList *list);
int qemu_set_option(const char *str);
diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index 3b098a9..000eae3 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -37,7 +37,6 @@
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);
void error_set_progname(const char *argv0);
void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
const char *error_get_progname(void);
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index cb4c1eb..c003c6a 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -22,6 +22,8 @@
#define KVM_DEV_FLIC_CLEAR_IRQS 3
#define KVM_DEV_FLIC_APF_ENABLE 4
#define KVM_DEV_FLIC_APF_DISABLE_WAIT 5
+#define KVM_DEV_FLIC_ADAPTER_REGISTER 6
+#define KVM_DEV_FLIC_ADAPTER_MODIFY 7
/*
* We can have up to 4*64k pending subchannels + 8 adapter interrupts,
* as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.
@@ -32,6 +34,26 @@
#define KVM_S390_MAX_FLOAT_IRQS 266250
#define KVM_S390_FLIC_MAX_BUFFER 0x2000000
+struct kvm_s390_io_adapter {
+ __u32 id;
+ __u8 isc;
+ __u8 maskable;
+ __u8 swap;
+ __u8 pad;
+};
+
+#define KVM_S390_IO_ADAPTER_MASK 1
+#define KVM_S390_IO_ADAPTER_MAP 2
+#define KVM_S390_IO_ADAPTER_UNMAP 3
+
+struct kvm_s390_io_adapter_req {
+ __u32 id;
+ __u8 type;
+ __u8 mask;
+ __u16 pad0;
+ __u64 addr;
+};
+
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
/* general purpose regs for s390 */
@@ -76,4 +98,6 @@
#define KVM_REG_S390_PFTOKEN (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x5)
#define KVM_REG_S390_PFCOMPARE (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x6)
#define KVM_REG_S390_PFSELECT (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x7)
+#define KVM_REG_S390_PP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x8)
+#define KVM_REG_S390_GBEA (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x9)
#endif
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index e27a4b3..b278ab3 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -740,6 +740,9 @@
#define KVM_CAP_SPAPR_MULTITCE 94
#define KVM_CAP_EXT_EMUL_CPUID 95
#define KVM_CAP_HYPERV_TIME 96
+#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97
+#define KVM_CAP_ENABLE_CAP_VM 98
+#define KVM_CAP_S390_IRQCHIP 99
#ifdef KVM_CAP_IRQ_ROUTING
@@ -755,9 +758,18 @@
__u32 pad;
};
+struct kvm_irq_routing_s390_adapter {
+ __u64 ind_addr;
+ __u64 summary_addr;
+ __u64 ind_offset;
+ __u32 summary_offset;
+ __u32 adapter_id;
+};
+
/* gsi routing entry types */
#define KVM_IRQ_ROUTING_IRQCHIP 1
#define KVM_IRQ_ROUTING_MSI 2
+#define KVM_IRQ_ROUTING_S390_ADAPTER 3
struct kvm_irq_routing_entry {
__u32 gsi;
@@ -767,6 +779,7 @@
union {
struct kvm_irq_routing_irqchip irqchip;
struct kvm_irq_routing_msi msi;
+ struct kvm_irq_routing_s390_adapter adapter;
__u32 pad[8];
} u;
};
@@ -1075,6 +1088,10 @@
/* Available with KVM_CAP_DEBUGREGS */
#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs)
#define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs)
+/*
+ * vcpu version available with KVM_ENABLE_CAP
+ * vm version available with KVM_CAP_ENABLE_CAP_VM
+ */
#define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap)
/* Available with KVM_CAP_XSAVE */
#define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave)
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 17c58e0..26c218e 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -23,6 +23,12 @@
#define VFIO_TYPE1_IOMMU 1
#define VFIO_SPAPR_TCE_IOMMU 2
+#define VFIO_TYPE1v2_IOMMU 3
+/*
+ * IOMMU enforces DMA cache coherence (ex. PCIe NoSnoop stripping). This
+ * capability is subject to change as groups are added or removed.
+ */
+#define VFIO_DMA_CC_IOMMU 4
/*
* The IOCTL interface is designed for extensibility by embedding the
diff --git a/monitor.c b/monitor.c
index 342e83b..1266ba0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -137,6 +137,7 @@
* used, and mhandler of 1st level plays the role of help function.
*/
struct mon_cmd_t *sub_table;
+ void (*command_completion)(ReadLineState *rs, int nb_args, const char *str);
} mon_cmd_t;
/* file descriptors passed via SCM_RIGHTS */
@@ -352,33 +353,6 @@
va_end(ap);
}
-void monitor_print_filename(Monitor *mon, const char *filename)
-{
- int i;
-
- for (i = 0; filename[i]; i++) {
- switch (filename[i]) {
- case ' ':
- case '"':
- case '\\':
- monitor_printf(mon, "\\%c", filename[i]);
- break;
- case '\t':
- monitor_printf(mon, "\\t");
- break;
- case '\r':
- monitor_printf(mon, "\\r");
- break;
- case '\n':
- monitor_printf(mon, "\\n");
- break;
- default:
- monitor_printf(mon, "%c", filename[i]);
- break;
- }
- }
-}
-
static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
const char *fmt, ...)
{
@@ -2254,6 +2228,7 @@
}
if (qemu_isdigit(fdname[0])) {
+ close(fd);
error_set(errp, QERR_INVALID_PARAMETER_VALUE, "fdname",
"a name not starting with a digit");
return;
@@ -4277,11 +4252,15 @@
return (p != NULL ? ++p : typestr);
}
-static void device_add_completion(ReadLineState *rs, const char *str)
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
{
GSList *list, *elt;
size_t len;
+ if (nb_args != 2) {
+ return;
+ }
+
len = strlen(str);
readline_set_completion_index(rs, len);
list = elt = object_class_get_list(TYPE_DEVICE, false);
@@ -4290,7 +4269,9 @@
DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
TYPE_DEVICE);
name = object_class_get_name(OBJECT_CLASS(dc));
- if (!strncmp(name, str, len)) {
+
+ if (!dc->cannot_instantiate_with_device_add_yet
+ && !strncmp(name, str, len)) {
readline_add_completion(rs, name);
}
elt = elt->next;
@@ -4298,11 +4279,15 @@
g_slist_free(list);
}
-static void object_add_completion(ReadLineState *rs, const char *str)
+void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
{
GSList *list, *elt;
size_t len;
+ if (nb_args != 2) {
+ return;
+ }
+
len = strlen(str);
readline_set_completion_index(rs, len);
list = elt = object_class_get_list(TYPE_USER_CREATABLE, false);
@@ -4318,8 +4303,8 @@
g_slist_free(list);
}
-static void device_del_completion(ReadLineState *rs, BusState *bus,
- const char *str, size_t len)
+static void device_del_bus_completion(ReadLineState *rs, BusState *bus,
+ const char *str, size_t len)
{
BusChild *kid;
@@ -4332,16 +4317,32 @@
}
QLIST_FOREACH(dev_child, &dev->child_bus, sibling) {
- device_del_completion(rs, dev_child, str, len);
+ device_del_bus_completion(rs, dev_child, str, len);
}
}
}
-static void object_del_completion(ReadLineState *rs, const char *str)
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+ size_t len;
+
+ if (nb_args != 2) {
+ return;
+ }
+
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+ device_del_bus_completion(rs, sysbus_get_default(), str, len);
+}
+
+void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
{
ObjectPropertyInfoList *list, *start;
size_t len;
+ if (nb_args != 2) {
+ return;
+ }
len = strlen(str);
readline_set_completion_index(rs, len);
@@ -4395,6 +4396,9 @@
return monitor_find_completion_by_table(mon, cmd->sub_table,
&args[1], nb_args - 1);
}
+ if (cmd->command_completion) {
+ return cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]);
+ }
ptype = next_arg_type(cmd->args_type);
for(i = 0; i < nb_args - 2; i++) {
@@ -4421,13 +4425,6 @@
readline_set_completion_index(mon->rs, strlen(str));
bdrv_iterate(block_completion_it, &mbs);
break;
- case 'O':
- if (!strcmp(cmd->name, "device_add") && nb_args == 2) {
- device_add_completion(mon->rs, str);
- } else if (!strcmp(cmd->name, "object_add") && nb_args == 2) {
- object_add_completion(mon->rs, str);
- }
- break;
case 's':
case 'S':
if (!strcmp(cmd->name, "sendkey")) {
@@ -4441,12 +4438,6 @@
} else if (!strcmp(cmd->name, "help|?")) {
monitor_find_completion_by_table(mon, cmd_table,
&args[1], nb_args - 1);
- } else if (!strcmp(cmd->name, "device_del") && nb_args == 2) {
- size_t len = strlen(str);
- readline_set_completion_index(mon->rs, len);
- device_del_completion(mon->rs, sysbus_get_default(), str, len);
- } else if (!strcmp(cmd->name, "object_del") && nb_args == 2) {
- object_del_completion(mon->rs, str);
}
break;
default:
diff --git a/net/net.c b/net/net.c
index a4aadff..9db4dba 100644
--- a/net/net.c
+++ b/net/net.c
@@ -473,7 +473,7 @@
if (ret == 0) {
nc->receive_disabled = 1;
- };
+ }
return ret;
}
@@ -1045,7 +1045,7 @@
if (nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC) {
if (has_name) {
error_setg(errp, "net client(%s) isn't a NIC", name);
- break;
+ return NULL;
}
continue;
}
@@ -1064,11 +1064,15 @@
} else if (has_name) {
error_setg(errp, "net client(%s) doesn't support"
" rx-filter querying", name);
+ return NULL;
+ }
+
+ if (has_name) {
break;
}
}
- if (filter_list == NULL && !error_is_set(errp) && has_name) {
+ if (filter_list == NULL && has_name) {
error_setg(errp, "invalid net client name: %s", name);
}
diff --git a/net/slirp.c b/net/slirp.c
index cce026b..8fddc03 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -527,6 +527,7 @@
"pid directory=%s\n"
"lock directory=%s\n"
"state directory=%s\n"
+ "ncalrpc dir=%s/ncalrpc\n"
"log file=%s/log.smbd\n"
"smb passwd file=%s/smbpasswd\n"
"security = user\n"
@@ -542,6 +543,7 @@
s->smb_dir,
s->smb_dir,
s->smb_dir,
+ s->smb_dir,
exported_dir,
passwd->pw_name
);
diff --git a/net/tap.c b/net/tap.c
index 8847ce1..fc1b865 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -367,11 +367,8 @@
if (pid == 0) {
int open_max = sysconf(_SC_OPEN_MAX), i;
- for (i = 0; i < open_max; i++) {
- if (i != STDIN_FILENO &&
- i != STDOUT_FILENO &&
- i != STDERR_FILENO &&
- i != fd) {
+ for (i = 3; i < open_max; i++) {
+ if (i != fd) {
close(i);
}
}
@@ -452,11 +449,8 @@
char br_buf[6+IFNAMSIZ] = {0};
char helper_cmd[PATH_MAX + sizeof(fd_buf) + sizeof(br_buf) + 15];
- for (i = 0; i < open_max; i++) {
- if (i != STDIN_FILENO &&
- i != STDOUT_FILENO &&
- i != STDERR_FILENO &&
- i != sv[1]) {
+ for (i = 3; i < open_max; i++) {
+ if (i != sv[1]) {
close(i);
}
}
diff --git a/pc-bios/qemu_logo.svg b/pc-bios/qemu_logo.svg
new file mode 100644
index 0000000..07b5b51
--- /dev/null
+++ b/pc-bios/qemu_logo.svg
@@ -0,0 +1,1010 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="351.84259"
+ height="111.86757"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="qemu_logo.svg">
+ <title
+ id="title3182">Kew the Angry Emu</title>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient4686">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4688" />
+ <stop
+ id="stop3956"
+ offset="0.75"
+ style="stop-color:#000000;stop-opacity:0.87843138;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.43921569;"
+ offset="0.75"
+ id="stop3958" />
+ <stop
+ id="stop3960"
+ offset="0.88"
+ style="stop-color:#181818;stop-opacity:1;" />
+ <stop
+ style="stop-color:#242424;stop-opacity:1;"
+ offset="0.88"
+ id="stop3962" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="1"
+ id="stop4690" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4467">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4469" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.8974359;"
+ offset="1"
+ id="stop4471" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4431">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4433" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4435" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4466">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4468" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4470" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4321">
+ <stop
+ style="stop-color:#ff6702;stop-opacity:1;"
+ offset="0"
+ id="stop4323" />
+ <stop
+ style="stop-color:#ff9a55;stop-opacity:1;"
+ offset="1"
+ id="stop4325" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4283">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4285" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4287" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4251">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4253" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4255" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4007">
+ <stop
+ style="stop-color:#ff6600;stop-opacity:1;"
+ offset="0"
+ id="stop4009" />
+ <stop
+ style="stop-color:#ff9148;stop-opacity:1;"
+ offset="1"
+ id="stop4011" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3999">
+ <stop
+ style="stop-color:#fff7f2;stop-opacity:1;"
+ offset="0"
+ id="stop4001" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4003" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3890">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3892" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3894" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3880">
+ <stop
+ style="stop-color:#eb7400;stop-opacity:1;"
+ offset="0"
+ id="stop3882" />
+ <stop
+ style="stop-color:#f7b06a;stop-opacity:1;"
+ offset="1"
+ id="stop3884" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4011">
+ <stop
+ style="stop-color:#042dc8;stop-opacity:1;"
+ offset="0"
+ id="stop4013" />
+ <stop
+ style="stop-color:#4260d5;stop-opacity:1;"
+ offset="1"
+ id="stop4015" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3879">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.90598291;"
+ offset="0"
+ id="stop3881" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3869">
+ <stop
+ style="stop-color:#c95000;stop-opacity:1;"
+ offset="0"
+ id="stop3871" />
+ <stop
+ style="stop-color:#ff9e5e;stop-opacity:1;"
+ offset="1"
+ id="stop3873" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3861">
+ <stop
+ style="stop-color:#f06000;stop-opacity:1;"
+ offset="0"
+ id="stop3863" />
+ <stop
+ style="stop-color:#ffccaa;stop-opacity:1;"
+ offset="1"
+ id="stop3865" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3826">
+ <stop
+ style="stop-color:#ff6600;stop-opacity:1;"
+ offset="0"
+ id="stop3828" />
+ <stop
+ style="stop-color:#ff893b;stop-opacity:1;"
+ offset="1"
+ id="stop3830" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3879-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.90598291;"
+ offset="0"
+ id="stop3881-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3869-5">
+ <stop
+ style="stop-color:#c95000;stop-opacity:1;"
+ offset="0"
+ id="stop3871-9" />
+ <stop
+ style="stop-color:#ff9e5e;stop-opacity:1;"
+ offset="1"
+ id="stop3873-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3879-4"
+ id="linearGradient3885-6"
+ x1="76.025352"
+ y1="124.8497"
+ x2="75.874107"
+ y2="143.03978"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3879-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3869-2">
+ <stop
+ style="stop-color:#c95000;stop-opacity:1;"
+ offset="0"
+ id="stop3871-99" />
+ <stop
+ style="stop-color:#ff9e5e;stop-opacity:1;"
+ offset="1"
+ id="stop3873-6" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4011"
+ id="radialGradient4017"
+ cx="66.639"
+ cy="93.096375"
+ fx="66.639"
+ fy="93.096375"
+ r="11.515625"
+ gradientTransform="matrix(0.23244854,1.600893,-1.0124495,0.14700695,145.40424,-26.300303)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3879-4-7"
+ id="linearGradient3885-6-2"
+ x1="76.025352"
+ y1="124.8497"
+ x2="75.874107"
+ y2="143.03978"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3879-4-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74-6" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4011-5"
+ id="radialGradient4017-7"
+ cx="66.639"
+ cy="93.096375"
+ fx="66.639"
+ fy="93.096375"
+ r="11.515625"
+ gradientTransform="matrix(0.99779178,6.8718773,-4.3459674,0.6310314,452.75975,-225.98471)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4011-5">
+ <stop
+ style="stop-color:#042dc8;stop-opacity:1;"
+ offset="0"
+ id="stop4013-1" />
+ <stop
+ style="stop-color:#4260d5;stop-opacity:1;"
+ offset="1"
+ id="stop4015-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3879-4-75"
+ id="linearGradient3885-6-8"
+ x1="76.025352"
+ y1="124.8497"
+ x2="75.874107"
+ y2="143.03978"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3879-4-75">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74-4" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4011-0"
+ id="radialGradient4017-5"
+ cx="66.639"
+ cy="93.096375"
+ fx="66.639"
+ fy="93.096375"
+ r="11.515625"
+ gradientTransform="matrix(0.23244854,1.600893,-1.0124495,0.14700695,146.34996,53.681728)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4011-0">
+ <stop
+ style="stop-color:#042dc8;stop-opacity:1;"
+ offset="0"
+ id="stop4013-4" />
+ <stop
+ style="stop-color:#4260d5;stop-opacity:1;"
+ offset="1"
+ id="stop4015-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4011-0"
+ id="linearGradient4117"
+ x1="107.03001"
+ y1="189.72537"
+ x2="107.18476"
+ y2="173.47537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3879-4-7-2"
+ id="linearGradient3885-6-2-8"
+ x1="76.025352"
+ y1="124.8497"
+ x2="75.874107"
+ y2="143.03978"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3879-4-7-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6-7-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74-6-9" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4011-5-1"
+ id="radialGradient4017-7-9"
+ cx="66.639"
+ cy="93.096375"
+ fx="66.639"
+ fy="93.096375"
+ r="11.515625"
+ gradientTransform="matrix(0.99779178,6.8718773,-4.3459674,0.6310314,448.94742,-406.99277)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4011-5-1">
+ <stop
+ style="stop-color:#042dc8;stop-opacity:1;"
+ offset="0"
+ id="stop4013-1-9" />
+ <stop
+ style="stop-color:#4260d5;stop-opacity:1;"
+ offset="1"
+ id="stop4015-3-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3879-4-7-2-7"
+ id="linearGradient3885-6-2-8-0"
+ x1="76.025352"
+ y1="124.8497"
+ x2="75.874107"
+ y2="143.03978"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3879-4-7-2-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6-7-9-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74-6-9-6" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4011-5-1-5"
+ id="radialGradient4017-7-9-5"
+ cx="66.639"
+ cy="93.096375"
+ fx="66.639"
+ fy="93.096375"
+ r="11.515625"
+ gradientTransform="matrix(0.55965334,3.8543806,-2.4376181,0.3539404,454.75182,-145.44353)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4011-5-1-5">
+ <stop
+ style="stop-color:#042dc8;stop-opacity:1;"
+ offset="0"
+ id="stop4013-1-9-6" />
+ <stop
+ style="stop-color:#4260d5;stop-opacity:1;"
+ offset="1"
+ id="stop4015-3-8-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3879-4-7-2-4"
+ id="linearGradient3885-6-2-8-4"
+ x1="76.025352"
+ y1="124.8497"
+ x2="75.874107"
+ y2="143.03978"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3879-4-7-2-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6-7-9-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74-6-9-3" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4011-5-1-7"
+ id="radialGradient4017-7-9-7"
+ cx="66.639"
+ cy="93.096375"
+ fx="66.639"
+ fy="93.096375"
+ r="11.515625"
+ gradientTransform="matrix(0.26837158,1.8482981,-1.1689154,0.16972569,466.57614,26.180822)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4011-5-1-7">
+ <stop
+ style="stop-color:#042dc8;stop-opacity:1;"
+ offset="0"
+ id="stop4013-1-9-1" />
+ <stop
+ style="stop-color:#4260d5;stop-opacity:1;"
+ offset="1"
+ id="stop4015-3-8-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3879-4-7-2-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6-7-9-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74-6-9-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4011-5-1-55">
+ <stop
+ style="stop-color:#000a30;stop-opacity:1;"
+ offset="0"
+ id="stop4013-1-9-8" />
+ <stop
+ style="stop-color:#4260d5;stop-opacity:1;"
+ offset="1"
+ id="stop4015-3-8-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3890-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3892-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3894-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3880-4">
+ <stop
+ style="stop-color:#eb7400;stop-opacity:1;"
+ offset="0"
+ id="stop3882-5" />
+ <stop
+ style="stop-color:#f7b06a;stop-opacity:1;"
+ offset="1"
+ id="stop3884-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3999-7">
+ <stop
+ style="stop-color:#fff7f2;stop-opacity:1;"
+ offset="0"
+ id="stop4001-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4003-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4007-9">
+ <stop
+ style="stop-color:#ff6600;stop-opacity:1;"
+ offset="0"
+ id="stop4009-1" />
+ <stop
+ style="stop-color:#ff9148;stop-opacity:1;"
+ offset="1"
+ id="stop4011-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4007-9-5">
+ <stop
+ style="stop-color:#ff6600;stop-opacity:1;"
+ offset="0"
+ id="stop4009-1-9" />
+ <stop
+ style="stop-color:#ff9148;stop-opacity:1;"
+ offset="1"
+ id="stop4011-9-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3999-7-1">
+ <stop
+ style="stop-color:#fff7f2;stop-opacity:1;"
+ offset="0"
+ id="stop4001-9-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4003-4-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4007-9-5-3">
+ <stop
+ style="stop-color:#ff6600;stop-opacity:1;"
+ offset="0"
+ id="stop4009-1-9-3" />
+ <stop
+ style="stop-color:#ff9148;stop-opacity:1;"
+ offset="1"
+ id="stop4011-9-5-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3999-7-1-4">
+ <stop
+ style="stop-color:#fff7f2;stop-opacity:1;"
+ offset="0"
+ id="stop4001-9-1-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4003-4-4-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3879-4-7-2-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.93162394;"
+ offset="0"
+ id="stop3881-6-7-9-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3883-74-6-9-87" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4011-5-1-1">
+ <stop
+ style="stop-color:#fde8a1;stop-opacity:1;"
+ offset="0"
+ id="stop4013-1-9-63" />
+ <stop
+ style="stop-color:#2947b9;stop-opacity:1;"
+ offset="1"
+ id="stop4015-3-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4466"
+ id="linearGradient4472"
+ x1="161.7561"
+ y1="540.72662"
+ x2="161.7561"
+ y2="579.80206"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4321"
+ id="radialGradient4474"
+ cx="130.8242"
+ cy="575.27838"
+ fx="130.8242"
+ fy="575.27838"
+ r="49.498173"
+ gradientTransform="matrix(0.95670828,0.96684666,-0.72623533,0.71862001,423.45109,35.05138)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4466-5"
+ id="linearGradient4472-9"
+ x1="161.7561"
+ y1="540.72662"
+ x2="161.7561"
+ y2="579.80206"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4466-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4468-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4470-3" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4321-0"
+ id="radialGradient4474-6"
+ cx="130.8242"
+ cy="575.27838"
+ fx="130.8242"
+ fy="575.27838"
+ r="49.498173"
+ gradientTransform="matrix(0.95670828,0.96684666,-0.72623533,0.71862001,442.64399,170.9169)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4321-0">
+ <stop
+ style="stop-color:#ff6702;stop-opacity:1;"
+ offset="0"
+ id="stop4323-3" />
+ <stop
+ style="stop-color:#ff9a55;stop-opacity:1;"
+ offset="1"
+ id="stop4325-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4466-5-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4468-2-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4470-3-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4321-0-0">
+ <stop
+ style="stop-color:#ff6702;stop-opacity:1;"
+ offset="0"
+ id="stop4323-3-9" />
+ <stop
+ style="stop-color:#ff9a55;stop-opacity:1;"
+ offset="1"
+ id="stop4325-1-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4466-5-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4468-2-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4470-3-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4321-0-7">
+ <stop
+ style="stop-color:#ff6702;stop-opacity:1;"
+ offset="0"
+ id="stop4323-3-3" />
+ <stop
+ style="stop-color:#ff9a55;stop-opacity:1;"
+ offset="1"
+ id="stop4325-1-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4431"
+ id="linearGradient4437"
+ x1="142.81854"
+ y1="831.52283"
+ x2="142.81854"
+ y2="878.90735"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4467"
+ id="radialGradient4475"
+ cx="116.51958"
+ cy="98.282051"
+ fx="116.51958"
+ fy="98.282051"
+ r="55.859375"
+ gradientTransform="matrix(0.97442557,1.5088911,-0.83559154,0.53961599,79.641615,-130.28522)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4431-3"
+ id="linearGradient4437-6"
+ x1="142.81854"
+ y1="831.52283"
+ x2="142.81854"
+ y2="878.90735"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4431-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4433-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4435-2" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4467-7"
+ id="radialGradient4475-0"
+ cx="116.51958"
+ cy="98.282051"
+ fx="116.51958"
+ fy="98.282051"
+ r="55.859375"
+ gradientTransform="matrix(0.97442557,1.5088911,-0.83559154,0.53961599,225.10358,63.664066)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient4467-7">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4469-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.8974359;"
+ offset="1"
+ id="stop4471-7" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.0170184"
+ inkscape:cx="539.34448"
+ inkscape:cy="-81.088823"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="992"
+ inkscape:window-height="547"
+ inkscape:window-x="30"
+ inkscape:window-y="24"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <sodipodi:guide
+ orientation="0,1"
+ position="52.563745,58.089579"
+ id="guide2989" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="54.584055,28.037549"
+ id="guide2991" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="51.048515,41.169529"
+ id="guide2993" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="77.817565,40.916989"
+ id="guide2995" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="51.048515,41.169529"
+ id="guide3017" />
+ <inkscape:grid
+ type="xygrid"
+ id="grid3019"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ originx="-62.341105px"
+ originy="-884.63528px" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="85.658895,8.3647193"
+ id="guide3021" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="106.6589,4.3647193"
+ id="guide3023" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="90.658895,17.364719"
+ id="guide3025" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="90.658895,-6.6352807"
+ id="guide3027" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="-0.341105,-14.635281"
+ id="guide3810" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="1.658895,-49.635281"
+ id="guide3814" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="-17.698248,11.257579"
+ id="guide3856" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="6.601806,11.257579"
+ id="guide3887" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="24.658283,58.089579"
+ id="guide4019" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="106.6589,-6.6352807"
+ id="guide4481" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="139.08747,-193.20671"
+ id="guide4483" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Kew the Angry Emu</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Benoît Canet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>CC BY 3.0</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>QEMU Community</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:date>2012-02-15</dc:date>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by/3.0/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>QEMU logo</rdf:li>
+ <rdf:li>QEMU mascot</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:source>http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg01961.html</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by/3.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-62.341105,-55.859333)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#radialGradient4475);fill-opacity:1;stroke:none"
+ d="m 118.2161,55.859333 c -30.850815,0 -55.874995,24.87043 -55.874995,55.562497 0,30.69207 25.02418,55.56249 55.874995,55.56249 10.09496,0 19.54625,-2.6525 27.71875,-7.3125 l 2.90625,7.3125 2.40625,0 20,0 0.125,0 -8.8125,-21.78124 c 7.21537,-9.3622 11.5,-21.07236 11.5,-33.78125 0,-30.692067 -24.99293,-55.562497 -55.84375,-55.562497 z"
+ id="path3834-7-7-2-5-5-0-5-4" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient4437);fill-opacity:1;stroke:none"
+ id="path3661"
+ sodipodi:cx="142.5"
+ sodipodi:cy="856.29077"
+ sodipodi:rx="35.357143"
+ sodipodi:ry="24.642857"
+ d="m 177.85714,856.29077 c 0,13.60988 -15.82993,24.64286 -35.35714,24.64286 -19.52721,0 -35.35714,-11.03298 -35.35714,-24.64286 0,-13.60987 15.82993,-24.64286 35.35714,-24.64286 19.52721,0 35.35714,11.03299 35.35714,24.64286 z"
+ transform="matrix(1.0465082,0,0,1.2920463,-31.641235,-1016.8612)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;stroke:none"
+ id="path4442"
+ sodipodi:cx="115.66247"
+ sodipodi:cy="856.39258"
+ sodipodi:rx="6.5659914"
+ sodipodi:ry="6.5659914"
+ d="m 122.22846,856.39258 c 0,3.6263 -2.9397,6.56599 -6.56599,6.56599 -3.6263,0 -6.56599,-2.93969 -6.56599,-6.56599 0,-3.6263 2.93969,-6.56599 6.56599,-6.56599 3.62629,0 6.56599,2.93969 6.56599,6.56599 z"
+ transform="translate(7.6700247,-777.60351)" />
+ <rect
+ style="fill:#000000;fill-opacity:1;stroke:none"
+ id="rect4444"
+ width="37.643608"
+ height="5.5005069"
+ x="125.01157"
+ y="65.255234"
+ transform="matrix(0.98974903,0.14281759,-0.18972639,0.981837,0,0)" />
+ <rect
+ style="fill:#000000;fill-opacity:1;stroke:none"
+ id="rect4446"
+ width="6.5659914"
+ height="2.9041886"
+ x="144.92451"
+ y="89.016899" />
+ <path
+ style="fill:#ff6600;fill-opacity:1"
+ d="m 103.38797,65.010543 c -0.057,2.18531 -3.865755,0.28296 -4.031245,2.78125 -4.22387,-1.88052 0.32884,2.87188 -0.0937,3.3125 l -0.0312,0 -0.3125,-0.0312 c -0.20386,-0.0728 -0.49977,-0.19904 -0.9375,-0.46875 -2.9499,2.35025 -3.02157,7.23369 -6.0625,9.9375 -1.99467,4.30504 -2.47977,8.98337 -3.9375,13.46875 -0.71796,4.30292 -1.34881,8.597857 -0.28125,12.906247 0.32053,3.50159 -0.68919,8.25865 2.5,10.71875 4.72728,3.88304 8.65575,8.79543 12.624995,13.46875 6.21914,7.65333 11.72948,15.86251 16.59375,24.4375 0.32431,-2.11756 1.10954,4.26459 2.53125,4.6875 -0.49161,-3.19231 -1.13213,-8.26328 -1.4375,-12.1875 -1.5814,-10.2909 -6.65305,-19.64903 -8.5625,-29.84375 -0.0587,-0.43037 -0.12809,-0.87203 -0.1875,-1.3125 l 0,-1.28125 -0.15625,0 c -0.62551,-5.04297 -0.8504,-10.46546 2.8125,-14.40625 3.73968,-3.772097 9.30633,-4.722447 13.8125,-7.343747 1.00194,-0.59119 2.04921,-1.07174 3.125,-1.40625 0.009,-0.003 0.0228,0.003 0.0312,0 3.11701,-0.96341 6.44862,-0.93323 9.6875,-0.40625 0.0479,0.008 0.10841,0.0233 0.15625,0.0312 0.29455,0.0493 0.61389,0.099 0.90625,0.15625 2.37136,0.21133 7.14463,1.13687 8,-0.5 -3.27225,-2.78631 -7.98526,-2.59211 -11.96875,-3.6875 -0.63059,-0.11469 -1.41182,-0.24041 -2.1875,-0.3125 l -3.90625,-0.875 -0.96875,-0.25 0,0.0312 -13.96875,-2.71875 c -0.22212,-0.20226 -0.46434,-0.40933 -0.6875,-0.5625 l 13.625,1.6875 0,-0.0625 c 0.48011,0.10699 0.95576,0.19361 1.4375,0.25 l 0,0.0312 9.625,1.78125 c 1.66103,0.61952 3.4322,1.08374 5.09375,1.1875 2.74263,0.39907 6.22526,4.49092 7.125,4.6875 -0.44096,-4.307 -4.7422,-6.23586 -8.3125,-7.5 -4.1712,-2.02803 -10.4023,-1.95417 -11.0625,-7.5625 -0.1756,-0.39076 -0.34902,-0.78118 -0.5625,-1.15625 l -1.625,-2.15625 0.0625,-0.0312 c -2.21724,-2.61691 -5.34011,-4.52196 -8.65625,-5.25 -3.2914,-1.13611 -6.98773,-2.2671 -10.46875,-2.71875 -1.18132,3.47826 -2.5031,-2.75561 -5.34375,-0.90625 -2.48996,0.29488 -2.14614,0.95256 -4,-0.625 z m 17.90625,10.15625 c 0.90187,-0.0238 1.93277,0.14208 2.96875,0.5 2.76259,0.95447 4.56151,2.96523 4.03125,4.5 -0.53026,1.53477 -3.20616,1.98572 -5.96875,1.03125 -2.76259,-0.95447 -4.5615,-2.93398 -4.03125,-4.46875 0.33141,-0.95923 1.49689,-1.52281 3,-1.5625 z"
+ id="path3499-9-7"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:95.54121399px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="184.89412"
+ y="166.37402"
+ id="text4477"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4479"
+ x="184.89412"
+ y="166.37402"
+ style="fill:#000000;fill-opacity:1">EMU</tspan></text>
+ </g>
+</svg>
diff --git a/po/Makefile b/po/Makefile
index 705166e..669f865 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -37,8 +37,8 @@
$(call quiet-command, msgfmt -o $@ $<, " GEN $@")
$(PO_PATH)/messages.po: $(SRC_PATH)/ui/gtk.c
- $(call quiet-command, cd $(SRC_PATH) && \
- (xgettext -o - --from-code=UTF-8 --foreign-user \
+ $(call quiet-command, ( cd $(SRC_PATH) && \
+ xgettext -o - --from-code=UTF-8 --foreign-user \
--package-name=QEMU --package-version=$(VERSION) \
--msgid-bugs-address=qemu-devel@nongnu.org -k_ -C ui/gtk.c | \
sed -e s/CHARSET/UTF-8/) >$@, " GEN $@")
diff --git a/po/de_DE.po b/po/de_DE.po
index fcbde95..dec68c9 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -10,7 +10,7 @@
"PO-Revision-Date: 2012-02-28 16:00+0100\n"
"Last-Translator: Kevin Wolf <kwolf@redhat.com>\n"
"Language-Team: Deutsch <de@li.org>\n"
-"Language: \n"
+"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 45b2c01..ec54eb9 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -10,7 +10,7 @@
"PO-Revision-Date: 2013-03-31 19:39+0200\n"
"Last-Translator: Aurelien Jarno <aurelien@aurel32.net>\n"
"Language-Team: French <FR@li.org>\n"
-"Language: \n"
+"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/hu.po b/po/hu.po
index 0a44c66..401ed21 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -10,7 +10,7 @@
"PO-Revision-Date: 2013-05-06 20:42+0200\n"
"Last-Translator: Ákos Kovács <akoskovacs@gmx.com>\n"
"Language-Team: Hungarian <hu@li.org>\n"
-"Language: \n"
+"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/it.po b/po/it.po
index 592d3d8..a62665c 100644
--- a/po/it.po
+++ b/po/it.po
@@ -10,7 +10,7 @@
"PO-Revision-Date: 2012-02-27 08:23+0100\n"
"Last-Translator: Paolo Bonzini <pbonzini@redhat.com>\n"
"Language-Team: Italian <it@li.org>\n"
-"Language: \n"
+"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/tr.po b/po/tr.po
index d57995a..d712ced 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -10,7 +10,7 @@
"PO-Revision-Date: 2013-04-22 18:35+0300\n"
"Last-Translator: Ozan ÇaÄŸlayan <ozancag@gmail.com>\n"
"Language-Team: Türkçe <>\n"
-"Language: \n"
+"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/qapi-schema.json b/qapi-schema.json
index 391356f..0b00427 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4285,10 +4285,13 @@
#
# Drivers that are supported in block device operations.
#
+# @host_device, @host_cdrom, @host_floppy: Since 2.1
+#
# Since: 2.0
##
{ 'enum': 'BlockdevDriver',
- 'data': [ 'file', 'http', 'https', 'ftp', 'ftps', 'tftp', 'vvfat', 'blkdebug',
+ 'data': [ 'file', 'host_device', 'host_cdrom', 'host_floppy',
+ 'http', 'https', 'ftp', 'ftps', 'tftp', 'vvfat', 'blkdebug',
'blkverify', 'bochs', 'cloop', 'cow', 'dmg', 'parallels', 'qcow',
'qcow2', 'qed', 'raw', 'vdi', 'vhdx', 'vmdk', 'vpc', 'quorum' ] }
@@ -4555,6 +4558,9 @@
'discriminator': 'driver',
'data': {
'file': 'BlockdevOptionsFile',
+ 'host_device':'BlockdevOptionsFile',
+ 'host_cdrom': 'BlockdevOptionsFile',
+ 'host_floppy':'BlockdevOptionsFile',
'http': 'BlockdevOptionsFile',
'https': 'BlockdevOptionsFile',
'ftp': 'BlockdevOptionsFile',
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 921de33..9c61449 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -80,7 +80,8 @@
return NULL;
}
if (!cmd->enabled) {
- error_set(errp, QERR_COMMAND_DISABLED, command);
+ error_setg(errp, "The command %s has been disabled for this instance",
+ command);
return NULL;
}
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index bf42c04..a2bed1e 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -71,7 +71,7 @@
GHashTable *h;
if (qiv->nb_stack >= QIV_STACK_SIZE) {
- error_set(errp, QERR_BUFFER_OVERRUN);
+ error_setg(errp, "An internal buffer overran");
return;
}
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 9268c87..6189780 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -422,12 +422,14 @@
* one child bus accept it nevertheless */
switch (dev->num_child_bus) {
case 0:
- qerror_report(QERR_DEVICE_NO_BUS, elem);
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "Device '%s' has no child bus", elem);
return NULL;
case 1:
return QLIST_FIRST(&dev->child_bus);
default:
- qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "Device '%s' has multiple child busses", elem);
if (!monitor_cur_is_qmp()) {
qbus_list_bus(dev);
}
@@ -505,14 +507,16 @@
return NULL;
}
if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) {
- qerror_report(QERR_BAD_BUS_FOR_DEVICE,
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "Device '%s' can't go on a %s bus",
driver, object_get_typename(OBJECT(bus)));
return NULL;
}
} else if (dc->bus_type != NULL) {
bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type);
if (!bus) {
- qerror_report(QERR_NO_BUS_FOR_DEVICE,
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "No '%s' bus found for device '%s'",
dc->bus_type, driver);
return NULL;
}
diff --git a/qemu-img.c b/qemu-img.c
index 4dae84a..968b4c8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -457,12 +457,12 @@
static void dump_json_image_check(ImageCheck *check, bool quiet)
{
- Error *errp = NULL;
+ Error *local_err = NULL;
QString *str;
QmpOutputVisitor *ov = qmp_output_visitor_new();
QObject *obj;
visit_type_ImageCheck(qmp_output_get_visitor(ov),
- &check, NULL, &errp);
+ &check, NULL, &local_err);
obj = qmp_output_get_qobject(ov);
str = qobject_to_json_pretty(obj);
assert(str != NULL);
@@ -1731,12 +1731,12 @@
static void dump_json_image_info_list(ImageInfoList *list)
{
- Error *errp = NULL;
+ Error *local_err = NULL;
QString *str;
QmpOutputVisitor *ov = qmp_output_visitor_new();
QObject *obj;
visit_type_ImageInfoList(qmp_output_get_visitor(ov),
- &list, NULL, &errp);
+ &list, NULL, &local_err);
obj = qmp_output_get_qobject(ov);
str = qobject_to_json_pretty(obj);
assert(str != NULL);
@@ -1748,12 +1748,12 @@
static void dump_json_image_info(ImageInfo *info)
{
- Error *errp = NULL;
+ Error *local_err = NULL;
QString *str;
QmpOutputVisitor *ov = qmp_output_visitor_new();
QObject *obj;
visit_type_ImageInfo(qmp_output_get_visitor(ov),
- &info, NULL, &errp);
+ &info, NULL, &local_err);
obj = qmp_output_get_qobject(ov);
str = qobject_to_json_pretty(obj);
assert(str != NULL);
diff --git a/qemu-options.hx b/qemu-options.hx
index 6457034..781af14 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -210,10 +210,13 @@
ETEXI
DEF("m", HAS_ARG, QEMU_OPTION_m,
- "-m megs set virtual RAM size to megs MB [default="
- stringify(DEFAULT_RAM_SIZE) "]\n", QEMU_ARCH_ALL)
+ "-m [size=]megs\n"
+ " configure guest RAM\n"
+ " size: initial amount of guest memory (default: "
+ stringify(DEFAULT_RAM_SIZE) "MiB)\n",
+ QEMU_ARCH_ALL)
STEXI
-@item -m @var{megs}
+@item -m [size=]@var{megs}
@findex -m
Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB. Optionally,
a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
@@ -408,7 +411,8 @@
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
" [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
" [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
- " [,serial=s][,addr=A][,id=name][,aio=threads|native]\n"
+ " [,serial=s][,addr=A][,rerror=ignore|stop|report]\n"
+ " [,werror=ignore|stop|report|enospc][,id=name][,aio=threads|native]\n"
" [,readonly=on|off][,copy-on-read=on|off]\n"
" [[,bps=b]|[[,bps_rd=r][,bps_wr=w]]]\n"
" [[,iops=i]|[[,iops_rd=r][,iops_wr=w]]]\n"
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index caa926e..ea8094d 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -143,6 +143,7 @@
{ SCMP_SYS(getsockname), 242 },
{ SCMP_SYS(getpeername), 242 },
{ SCMP_SYS(accept4), 242 },
+ { SCMP_SYS(timerfd_settime), 242 },
{ SCMP_SYS(newfstatat), 241 },
{ SCMP_SYS(shutdown), 241 },
{ SCMP_SYS(getsockopt), 241 },
@@ -225,7 +226,11 @@
{ SCMP_SYS(fchmod), 240 },
{ SCMP_SYS(shmget), 240 },
{ SCMP_SYS(shmat), 240 },
- { SCMP_SYS(shmdt), 240 }
+ { SCMP_SYS(shmdt), 240 },
+ { SCMP_SYS(timerfd_create), 240 },
+ { SCMP_SYS(shmctl), 240 },
+ { SCMP_SYS(mlock), 240 },
+ { SCMP_SYS(munlock), 240 }
};
int seccomp_start(void)
diff --git a/qmp.c b/qmp.c
index 87a28f7..74107be 100644
--- a/qmp.c
+++ b/qmp.c
@@ -166,7 +166,7 @@
Error *local_err = NULL;
if (runstate_needs_reset()) {
- error_set(errp, QERR_RESET_REQUIRED);
+ error_setg(errp, "Resetting the Virtual Machine is required");
return;
} else if (runstate_check(RUN_STATE_SUSPENDED)) {
return;
@@ -540,14 +540,27 @@
Visitor *v, Error **errp)
{
Object *obj;
+ ObjectClass *klass;
const QDictEntry *e;
Error *local_err = NULL;
- if (!object_class_by_name(type)) {
+ klass = object_class_by_name(type);
+ if (!klass) {
error_setg(errp, "invalid class name");
return;
}
+ if (!object_class_dynamic_cast(klass, TYPE_USER_CREATABLE)) {
+ error_setg(errp, "object type '%s' isn't supported by object-add",
+ type);
+ return;
+ }
+
+ if (object_class_is_abstract(klass)) {
+ error_setg(errp, "object type '%s' is abstract", type);
+ return;
+ }
+
obj = object_new(type);
if (qdict) {
for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
@@ -558,12 +571,6 @@
}
}
- if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
- error_setg(&local_err, "object type '%s' isn't supported by object-add",
- type);
- goto out;
- }
-
user_creatable_complete(obj, &local_err);
if (local_err) {
goto out;
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index e7947b3..e46c264 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -110,7 +110,7 @@
error_free(ctxt->err);
ctxt->err = NULL;
}
- error_set(&ctxt->err, QERR_JSON_PARSE_ERROR, message);
+ error_setg(&ctxt->err, "JSON parse error, %s", message);
}
/**
diff --git a/qom/object.c b/qom/object.c
index 9a730e7..e42b254 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -768,7 +768,7 @@
}
}
- error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
+ error_setg(errp, "Property '.%s' not found", name);
return NULL;
}
@@ -1075,7 +1075,8 @@
target = object_resolve_path_type(path, target_type, &ambiguous);
if (ambiguous) {
- error_set(errp, QERR_AMBIGUOUS_PATH, path);
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Path '%s' does not uniquely identify an object", path);
} else if (!target) {
target = object_resolve_path(path, &ambiguous);
if (target || ambiguous) {
diff --git a/savevm.c b/savevm.c
index 22123be..da8aa24 100644
--- a/savevm.c
+++ b/savevm.c
@@ -453,7 +453,8 @@
QTAILQ_FOREACH(se, &savevm_handlers, entry) {
if (se->no_migrate) {
- error_set(errp, QERR_MIGRATION_NOT_SUPPORTED, se->idstr);
+ error_setg(errp, "State blocked by non-migratable device '%s'",
+ se->idstr);
return true;
}
}
diff --git a/slirp/misc.c b/slirp/misc.c
index 6c1636f..b8eb74c 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -136,7 +136,7 @@
if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
listen(s, 1) < 0) {
- lprint("Error: inet socket: %s\n", strerror(errno));
+ error_report("Error: inet socket: %s", strerror(errno));
closesocket(s);
return 0;
@@ -146,7 +146,7 @@
pid = fork();
switch(pid) {
case -1:
- lprint("Error: fork failed: %s\n", strerror(errno));
+ error_report("Error: fork failed: %s", strerror(errno));
close(s);
return 0;
@@ -242,15 +242,6 @@
}
#endif
-void lprint(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- monitor_vprintf(default_mon, format, args);
- va_end(args);
-}
-
void slirp_connection_info(Slirp *slirp, Monitor *mon)
{
const char * const tcpstates[] = {
diff --git a/slirp/slirp.c b/slirp/slirp.c
index bad8dad..3fb48a4 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -139,7 +139,7 @@
return -1;
#ifdef DEBUG
- lprint("IP address of your DNS(s): ");
+ fprintf(stderr, "IP address of your DNS(s): ");
#endif
while (fgets(buff, 512, f) != NULL) {
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
@@ -153,17 +153,17 @@
}
#ifdef DEBUG
else
- lprint(", ");
+ fprintf(stderr, ", ");
#endif
if (++found > 3) {
#ifdef DEBUG
- lprint("(more)");
+ fprintf(stderr, "(more)");
#endif
break;
}
#ifdef DEBUG
else
- lprint("%s", inet_ntoa(tmp_addr));
+ fprintf(stderr, "%s", inet_ntoa(tmp_addr));
#endif
}
}
diff --git a/slirp/slirp.h b/slirp/slirp.h
index e4a1bd4..6589d7e 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -287,8 +287,6 @@
long gethostid(void);
#endif
-void lprint(const char *, ...) GCC_FMT_ATTR(1, 2);
-
#ifndef _WIN32
#include <netdb.h>
#endif
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5ed1d38..d99e2b9 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -14,7 +14,6 @@
stub-obj-y += migr-blocker.o
stub-obj-y += mon-is-qmp.o
stub-obj-y += mon-printf.o
-stub-obj-y += mon-print-filename.o
stub-obj-y += mon-protocol-event.o
stub-obj-y += mon-set-error.o
stub-obj-y += pci-drive-hot-add.o
diff --git a/stubs/arch-query-cpu-def.c b/stubs/arch-query-cpu-def.c
index fa67895..22e0b43 100644
--- a/stubs/arch-query-cpu-def.c
+++ b/stubs/arch-query-cpu-def.c
@@ -4,6 +4,6 @@
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
{
- error_set(errp, QERR_NOT_SUPPORTED);
+ error_set(errp, QERR_UNSUPPORTED);
return NULL;
}
diff --git a/stubs/mon-print-filename.c b/stubs/mon-print-filename.c
deleted file mode 100644
index 9c93964..0000000
--- a/stubs/mon-print-filename.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "qemu-common.h"
-#include "monitor/monitor.h"
-
-void monitor_print_filename(Monitor *mon, const char *filename)
-{
-}
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index f332d41..41903a9 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -126,6 +126,9 @@
uint64_t pfault_compare;
uint64_t pfault_select;
+ uint64_t gbea;
+ uint64_t pp;
+
CPU_COMMON
/* reset does memset(0) up to here */
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 56b9af7..a30d1bc 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -36,6 +36,7 @@
#include "sysemu/device_tree.h"
#include "qapi/qmp/qjson.h"
#include "monitor/monitor.h"
+#include "trace.h"
/* #define DEBUG_KVM */
@@ -128,14 +129,42 @@
}
}
+static int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source)
+{
+ struct kvm_one_reg reg;
+ int r;
+
+ reg.id = id;
+ reg.addr = (uint64_t) source;
+ r = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+ if (r) {
+ trace_kvm_failed_reg_set(id, strerror(errno));
+ }
+ return r;
+}
+
+static int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target)
+{
+ struct kvm_one_reg reg;
+ int r;
+
+ reg.id = id;
+ reg.addr = (uint64_t) target;
+ r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ if (r) {
+ trace_kvm_failed_reg_get(id, strerror(errno));
+ }
+ return r;
+}
+
+
int kvm_arch_put_registers(CPUState *cs, int level)
{
S390CPU *cpu = S390_CPU(cs);
CPUS390XState *env = &cpu->env;
- struct kvm_one_reg reg;
struct kvm_sregs sregs;
struct kvm_regs regs;
- int ret;
+ int r;
int i;
/* always save the PSW and the GPRS*/
@@ -151,9 +180,9 @@
for (i = 0; i < 16; i++) {
regs.gprs[i] = env->regs[i];
}
- ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s);
- if (ret < 0) {
- return ret;
+ r = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s);
+ if (r < 0) {
+ return r;
}
}
@@ -162,47 +191,29 @@
return 0;
}
- reg.id = KVM_REG_S390_CPU_TIMER;
- reg.addr = (__u64)&(env->cputm);
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
- if (ret < 0) {
- return ret;
- }
-
- reg.id = KVM_REG_S390_CLOCK_COMP;
- reg.addr = (__u64)&(env->ckc);
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
- if (ret < 0) {
- return ret;
- }
-
- reg.id = KVM_REG_S390_TODPR;
- reg.addr = (__u64)&(env->todpr);
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
- if (ret < 0) {
- return ret;
- }
+ /*
+ * These ONE_REGS are not protected by a capability. As they are only
+ * necessary for migration we just trace a possible error, but don't
+ * return with an error return code.
+ */
+ kvm_set_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm);
+ kvm_set_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc);
+ kvm_set_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
+ kvm_set_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea);
+ kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp);
if (cap_async_pf) {
- reg.id = KVM_REG_S390_PFTOKEN;
- reg.addr = (__u64)&(env->pfault_token);
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
- if (ret < 0) {
- return ret;
+ r = kvm_set_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token);
+ if (r < 0) {
+ return r;
}
-
- reg.id = KVM_REG_S390_PFCOMPARE;
- reg.addr = (__u64)&(env->pfault_compare);
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
- if (ret < 0) {
- return ret;
+ r = kvm_set_one_reg(cs, KVM_REG_S390_PFCOMPARE, &env->pfault_compare);
+ if (r < 0) {
+ return r;
}
-
- reg.id = KVM_REG_S390_PFSELECT;
- reg.addr = (__u64)&(env->pfault_select);
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
- if (ret < 0) {
- return ret;
+ r = kvm_set_one_reg(cs, KVM_REG_S390_PFSELECT, &env->pfault_select);
+ if (r < 0) {
+ return r;
}
}
@@ -220,9 +231,9 @@
sregs.acrs[i] = env->aregs[i];
sregs.crs[i] = env->cregs[i];
}
- ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
- if (ret < 0) {
- return ret;
+ r = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
+ if (r < 0) {
+ return r;
}
}
@@ -240,7 +251,6 @@
{
S390CPU *cpu = S390_CPU(cs);
CPUS390XState *env = &cpu->env;
- struct kvm_one_reg reg;
struct kvm_sregs sregs;
struct kvm_regs regs;
int i, r;
@@ -288,46 +298,27 @@
env->psa = cs->kvm_run->s.regs.prefix;
}
- /* One Regs */
- reg.id = KVM_REG_S390_CPU_TIMER;
- reg.addr = (__u64)&(env->cputm);
- r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
- if (r < 0) {
- return r;
- }
-
- reg.id = KVM_REG_S390_CLOCK_COMP;
- reg.addr = (__u64)&(env->ckc);
- r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
- if (r < 0) {
- return r;
- }
-
- reg.id = KVM_REG_S390_TODPR;
- reg.addr = (__u64)&(env->todpr);
- r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
- if (r < 0) {
- return r;
- }
+ /*
+ * These ONE_REGS are not protected by a capability. As they are only
+ * necessary for migration we just trace a possible error, but don't
+ * return with an error return code.
+ */
+ kvm_get_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm);
+ kvm_get_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc);
+ kvm_get_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
+ kvm_get_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea);
+ kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp);
if (cap_async_pf) {
- reg.id = KVM_REG_S390_PFTOKEN;
- reg.addr = (__u64)&(env->pfault_token);
- r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ r = kvm_get_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token);
if (r < 0) {
return r;
}
-
- reg.id = KVM_REG_S390_PFCOMPARE;
- reg.addr = (__u64)&(env->pfault_compare);
- r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ r = kvm_get_one_reg(cs, KVM_REG_S390_PFCOMPARE, &env->pfault_compare);
if (r < 0) {
return r;
}
-
- reg.id = KVM_REG_S390_PFSELECT;
- reg.addr = (__u64)&(env->pfault_select);
- r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+ r = kvm_get_one_reg(cs, KVM_REG_S390_PFSELECT, &env->pfault_select);
if (r < 0) {
return r;
}
@@ -383,6 +374,26 @@
return 0;
}
+int kvm_arch_insert_hw_breakpoint(target_ulong addr,
+ target_ulong len, int type)
+{
+ return -ENOSYS;
+}
+
+int kvm_arch_remove_hw_breakpoint(target_ulong addr,
+ target_ulong len, int type)
+{
+ return -ENOSYS;
+}
+
+void kvm_arch_remove_all_hw_breakpoints(void)
+{
+}
+
+void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
+{
+}
+
void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
{
}
@@ -844,6 +855,11 @@
return ret;
}
+static int kvm_arch_handle_debug_exit(S390CPU *cpu)
+{
+ return -ENOSYS;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
S390CPU *cpu = S390_CPU(cs);
@@ -859,6 +875,9 @@
case KVM_EXIT_S390_TSCH:
ret = handle_tsch(cpu);
break;
+ case KVM_EXIT_DEBUG:
+ ret = kvm_arch_handle_debug_exit(cpu);
+ break;
default:
fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
break;
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 294b3ed..cdbbb79 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -336,7 +336,7 @@
ebcdic_put(sysib.model, "QEMU ", 16);
ebcdic_put(sysib.sequence, "QEMU ", 16);
ebcdic_put(sysib.plant, "QEMU", 4);
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else if ((sel1 == 2) && (sel2 == 1)) {
/* Basic Machine CPU */
struct sysib_121 sysib;
@@ -346,7 +346,7 @@
ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
ebcdic_put(sysib.plant, "QEMU", 4);
stw_p(&sysib.cpu_addr, env->cpu_num);
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else if ((sel1 == 2) && (sel2 == 2)) {
/* Basic Machine CPUs */
struct sysib_122 sysib;
@@ -358,7 +358,7 @@
stw_p(&sysib.active_cpus, 1);
stw_p(&sysib.standby_cpus, 0);
stw_p(&sysib.reserved_cpus, 0);
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else {
cc = 3;
}
@@ -375,7 +375,7 @@
ebcdic_put(sysib.plant, "QEMU", 4);
stw_p(&sysib.cpu_addr, env->cpu_num);
stw_p(&sysib.cpu_id, 0);
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else if ((sel1 == 2) && (sel2 == 2)) {
/* LPAR CPUs */
struct sysib_222 sysib;
@@ -392,7 +392,7 @@
stl_p(&sysib.caf, 1000);
stw_p(&sysib.dedicated_cpus, 0);
stw_p(&sysib.shared_cpus, 0);
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else {
cc = 3;
}
@@ -414,7 +414,7 @@
ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
stl_p(&sysib.vm[0].caf, 1000);
ebcdic_put(sysib.vm[0].cpi, "KVM/Linux ", 16);
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_write(a0, &sysib, sizeof(sysib));
} else {
cc = 3;
}
diff --git a/tcg/README b/tcg/README
index 776e925..a550ff1 100644
--- a/tcg/README
+++ b/tcg/README
@@ -314,6 +314,11 @@
dest = (t1 & ~0x0f00) | ((t2 << 8) & 0x0f00)
+* trunc_shr_i32 t0, t1, pos
+
+For 64-bit hosts only, right shift the 64-bit input T1 by POS and
+truncate to 32-bit output T0. Depending on the host, this may be
+a simple mov/shift, or may require additional canonicalization.
********* Conditional moves
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index eff1d68..a1d4322 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -68,6 +68,7 @@
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
+#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index ababca0..dbeb16d 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -99,6 +99,7 @@
#define TCG_TARGET_HAS_mulsh_i32 0
#if TCG_TARGET_REG_BITS == 64
+#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index 09c3ba8..d834beb 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -152,6 +152,7 @@
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_mulsh_i64 0
+#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_new_ldst 1
diff --git a/tcg/optimize.c b/tcg/optimize.c
index c447062..0302f4f 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -228,6 +228,7 @@
case INDEX_op_shr_i32:
return (uint32_t)x >> (y & 31);
+ case INDEX_op_trunc_shr_i32:
case INDEX_op_shr_i64:
return (uint64_t)x >> (y & 63);
@@ -830,6 +831,10 @@
}
break;
+ case INDEX_op_trunc_shr_i32:
+ mask = (uint64_t)temps[args[1]].mask >> args[2];
+ break;
+
CASE_OP_32_64(shl):
if (temps[args[2]].state == TCG_TEMP_CONST) {
tmp = temps[args[2]].val & (TCG_TARGET_REG_BITS - 1);
@@ -1021,6 +1026,17 @@
}
goto do_default;
+ case INDEX_op_trunc_shr_i32:
+ if (temps[args[1]].state == TCG_TEMP_CONST) {
+ s->gen_opc_buf[op_index] = op_to_movi(op);
+ tmp = do_constant_folding(op, temps[args[1]].val, args[2]);
+ tcg_opt_gen_movi(gen_args, args[0], tmp);
+ gen_args += 2;
+ args += 3;
+ break;
+ }
+ goto do_default;
+
CASE_OP_32_64(add):
CASE_OP_32_64(sub):
CASE_OP_32_64(mul):
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 78bbf7a..3815b84 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -96,6 +96,7 @@
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
+#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index b3bfdcc..755c002 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -69,6 +69,7 @@
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
+#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 35089b8..5468ff5 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -61,6 +61,24 @@
};
#endif
+#ifdef __arch64__
+# define SPARC64 1
+#else
+# define SPARC64 0
+#endif
+
+/* Note that sparcv8plus can only hold 64 bit quantities in %g and %o
+ registers. These are saved manually by the kernel in full 64-bit
+ slots. The %i and %l registers are saved by the register window
+ mechanism, which only allocates space for 32 bits. Given that this
+ window spill/fill can happen on any signal, we must consider the
+ high bits of the %i and %l registers garbage at all times. */
+#if SPARC64
+# define ALL_64 0xffffffffu
+#else
+# define ALL_64 0xffffu
+#endif
+
/* Define some temporary registers. T2 is used for constant generation. */
#define TCG_REG_T1 TCG_REG_G1
#define TCG_REG_T2 TCG_REG_O7
@@ -182,6 +200,7 @@
#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x08))
#define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
+#define ARITH_SMUL (INSN_OP(2) | INSN_OP3(0x0b))
#define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
#define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
#define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
@@ -201,6 +220,7 @@
#define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
#define WRY (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
#define JMPL (INSN_OP(2) | INSN_OP3(0x38))
+#define RETURN (INSN_OP(2) | INSN_OP3(0x39))
#define SAVE (INSN_OP(2) | INSN_OP3(0x3c))
#define RESTORE (INSN_OP(2) | INSN_OP3(0x3d))
#define SETHI (INSN_OP(0) | INSN_OP2(0x4))
@@ -242,17 +262,23 @@
#define STW_LE (STWA | INSN_ASI(ASI_PRIMARY_LITTLE))
#define STX_LE (STXA | INSN_ASI(ASI_PRIMARY_LITTLE))
-static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
+static inline int check_fit_i64(int64_t val, unsigned int bits)
{
- return (val << ((sizeof(tcg_target_long) * 8 - bits))
- >> (sizeof(tcg_target_long) * 8 - bits)) == val;
+ return val == sextract64(val, 0, bits);
}
-static inline int check_fit_i32(uint32_t val, unsigned int bits)
+static inline int check_fit_i32(int32_t val, unsigned int bits)
{
- return ((val << (32 - bits)) >> (32 - bits)) == val;
+ return val == sextract32(val, 0, bits);
}
+#define check_fit_tl check_fit_i64
+#if SPARC64
+# define check_fit_ptr check_fit_i64
+#else
+# define check_fit_ptr check_fit_i32
+#endif
+
static void patch_reloc(uint8_t *code_ptr, int type,
intptr_t value, intptr_t addend)
{
@@ -267,7 +293,7 @@
break;
case R_SPARC_WDISP16:
value -= (intptr_t)code_ptr;
- if (!check_fit_tl(value >> 2, 16)) {
+ if (!check_fit_ptr(value >> 2, 16)) {
tcg_abort();
}
insn = *(uint32_t *)code_ptr;
@@ -277,7 +303,7 @@
break;
case R_SPARC_WDISP19:
value -= (intptr_t)code_ptr;
- if (!check_fit_tl(value >> 2, 19)) {
+ if (!check_fit_ptr(value >> 2, 19)) {
tcg_abort();
}
insn = *(uint32_t *)code_ptr;
@@ -301,14 +327,27 @@
ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
break;
- case 'L': /* qemu_ld/st constraint */
+ case 'R':
ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- // Helper args
+ tcg_regset_set32(ct->u.regs, 0, ALL_64);
+ break;
+ case 'A': /* qemu_ld/st address constraint */
+ ct->ct |= TCG_CT_REG;
+ tcg_regset_set32(ct->u.regs, 0,
+ TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff);
+ reserve_helpers:
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
break;
+ case 's': /* qemu_st data 32-bit constraint */
+ ct->ct |= TCG_CT_REG;
+ tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
+ goto reserve_helpers;
+ case 'S': /* qemu_st data 64-bit constraint */
+ ct->ct |= TCG_CT_REG;
+ tcg_regset_set32(ct->u.regs, 0, ALL_64);
+ goto reserve_helpers;
case 'I':
ct->ct |= TCG_CT_CONST_S11;
break;
@@ -351,22 +390,20 @@
}
}
-static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
- int op)
+static inline void tcg_out_arith(TCGContext *s, TCGReg rd, TCGReg rs1,
+ TCGReg rs2, int op)
{
- tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
- INSN_RS2(rs2));
+ tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) | INSN_RS2(rs2));
}
-static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
- uint32_t offset, int op)
+static inline void tcg_out_arithi(TCGContext *s, TCGReg rd, TCGReg rs1,
+ int32_t offset, int op)
{
- tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
- INSN_IMM13(offset));
+ tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) | INSN_IMM13(offset));
}
-static void tcg_out_arithc(TCGContext *s, int rd, int rs1,
- int val2, int val2const, int op)
+static void tcg_out_arithc(TCGContext *s, TCGReg rd, TCGReg rs1,
+ int32_t val2, int val2const, int op)
{
tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
| (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
@@ -380,12 +417,12 @@
}
}
-static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
+static inline void tcg_out_sethi(TCGContext *s, TCGReg ret, uint32_t arg)
{
tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
}
-static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
+static inline void tcg_out_movi_imm13(TCGContext *s, TCGReg ret, int32_t arg)
{
tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
}
@@ -393,7 +430,12 @@
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
- tcg_target_long hi, lo;
+ tcg_target_long hi, lo = (int32_t)arg;
+
+ /* Make sure we test 32-bit constants for imm13 properly. */
+ if (type == TCG_TYPE_I32) {
+ arg = lo;
+ }
/* A 13-bit constant sign-extended to 64-bits. */
if (check_fit_tl(arg, 13)) {
@@ -402,9 +444,7 @@
}
/* A 32-bit constant, or 32-bit zero-extended to 64-bits. */
- if (TCG_TARGET_REG_BITS == 32
- || type == TCG_TYPE_I32
- || (arg & ~0xffffffffu) == 0) {
+ if (type == TCG_TYPE_I32 || arg == (uint32_t)arg) {
tcg_out_sethi(s, ret, arg);
if (arg & 0x3ff) {
tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
@@ -413,21 +453,20 @@
}
/* A 32-bit constant sign-extended to 64-bits. */
- if (check_fit_tl(arg, 32)) {
+ if (arg == lo) {
tcg_out_sethi(s, ret, ~arg);
tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
return;
}
/* A 64-bit constant decomposed into 2 32-bit pieces. */
- lo = (int32_t)arg;
- if (check_fit_tl(lo, 13)) {
- hi = (arg - lo) >> 31 >> 1;
+ if (check_fit_i32(lo, 13)) {
+ hi = (arg - lo) >> 32;
tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
tcg_out_arithi(s, ret, ret, lo, ARITH_ADD);
} else {
- hi = arg >> 31 >> 1;
+ hi = arg >> 32;
tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T2, lo);
tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
@@ -435,16 +474,16 @@
}
}
-static inline void tcg_out_ldst_rr(TCGContext *s, int data, int a1,
- int a2, int op)
+static inline void tcg_out_ldst_rr(TCGContext *s, TCGReg data, TCGReg a1,
+ TCGReg a2, int op)
{
tcg_out32(s, op | INSN_RD(data) | INSN_RS1(a1) | INSN_RS2(a2));
}
-static inline void tcg_out_ldst(TCGContext *s, int ret, int addr,
- int offset, int op)
+static void tcg_out_ldst(TCGContext *s, TCGReg ret, TCGReg addr,
+ intptr_t offset, int op)
{
- if (check_fit_tl(offset, 13)) {
+ if (check_fit_ptr(offset, 13)) {
tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
INSN_IMM13(offset));
} else {
@@ -465,40 +504,24 @@
tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
}
-static inline void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
+static void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
{
- TCGReg base = TCG_REG_G0;
- if (!check_fit_tl(arg, 10)) {
- tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
- base = ret;
- }
- tcg_out_ld(s, TCG_TYPE_PTR, ret, base, arg & 0x3ff);
+ tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
+ tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
}
-static inline void tcg_out_sety(TCGContext *s, int rs)
+static inline void tcg_out_sety(TCGContext *s, TCGReg rs)
{
tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
}
-static inline void tcg_out_rdy(TCGContext *s, int rd)
+static inline void tcg_out_rdy(TCGContext *s, TCGReg rd)
{
tcg_out32(s, RDY | INSN_RD(rd));
}
-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- if (val != 0) {
- if (check_fit_tl(val, 13))
- tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
- else {
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, val);
- tcg_out_arith(s, reg, reg, TCG_REG_T1, ARITH_ADD);
- }
- }
-}
-
-static void tcg_out_div32(TCGContext *s, int rd, int rs1,
- int val2, int val2const, int uns)
+static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
+ int32_t val2, int val2const, int uns)
{
/* Load Y with the sign/zero extension of RS1 to 64-bits. */
if (uns) {
@@ -559,38 +582,37 @@
tcg_out_bpcc0(s, scond, flags, off19);
}
-static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const)
+static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
{
tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
}
-static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGArg arg1,
- TCGArg arg2, int const_arg2, int label)
+static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
+ int32_t arg2, int const_arg2, int label)
{
tcg_out_cmp(s, arg1, arg2, const_arg2);
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, label);
tcg_out_nop(s);
}
-static void tcg_out_movcc(TCGContext *s, TCGCond cond, int cc, TCGArg ret,
- TCGArg v1, int v1const)
+static void tcg_out_movcc(TCGContext *s, TCGCond cond, int cc, TCGReg ret,
+ int32_t v1, int v1const)
{
tcg_out32(s, ARITH_MOVCC | cc | INSN_RD(ret)
| INSN_RS1(tcg_cond_to_bcond[cond])
| (v1const ? INSN_IMM11(v1) : INSN_RS2(v1)));
}
-static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
- TCGArg c1, TCGArg c2, int c2const,
- TCGArg v1, int v1const)
+static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg c1, int32_t c2, int c2const,
+ int32_t v1, int v1const)
{
tcg_out_cmp(s, c1, c2, c2const);
tcg_out_movcc(s, cond, MOVCC_ICC, ret, v1, v1const);
}
-#if TCG_TARGET_REG_BITS == 64
-static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1,
- TCGArg arg2, int const_arg2, int label)
+static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
+ int32_t arg2, int const_arg2, int label)
{
/* For 64-bit signed comparisons vs zero, we can avoid the compare. */
if (arg2 == 0 && !is_unsigned_cond(cond)) {
@@ -613,71 +635,32 @@
tcg_out_nop(s);
}
-static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGArg ret, TCGArg c1,
- TCGArg v1, int v1const)
+static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1,
+ int32_t v1, int v1const)
{
tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
| (tcg_cond_to_rcond[cond] << 10)
| (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
}
-static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
- TCGArg c1, TCGArg c2, int c2const,
- TCGArg v1, int v1const)
+static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg c1, int32_t c2, int c2const,
+ int32_t v1, int v1const)
{
/* For 64-bit signed comparisons vs zero, we can avoid the compare.
Note that the immediate range is one bit smaller, so we must check
for that as well. */
if (c2 == 0 && !is_unsigned_cond(cond)
- && (!v1const || check_fit_tl(v1, 10))) {
+ && (!v1const || check_fit_i32(v1, 10))) {
tcg_out_movr(s, cond, ret, c1, v1, v1const);
} else {
tcg_out_cmp(s, c1, c2, c2const);
tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
}
}
-#else
-static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
- TCGArg al, TCGArg ah,
- TCGArg bl, int blconst,
- TCGArg bh, int bhconst, int label_dest)
-{
- int scond, label_next = gen_new_label();
- tcg_out_cmp(s, ah, bh, bhconst);
-
- /* Note that we fill one of the delay slots with the second compare. */
- switch (cond) {
- case TCG_COND_EQ:
- tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_next);
- tcg_out_cmp(s, al, bl, blconst);
- tcg_out_bpcc(s, COND_E, BPCC_ICC | BPCC_PT, label_dest);
- break;
-
- case TCG_COND_NE:
- tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_dest);
- tcg_out_cmp(s, al, bl, blconst);
- tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_dest);
- break;
-
- default:
- scond = tcg_cond_to_bcond[tcg_high_cond(cond)];
- tcg_out_bpcc(s, scond, BPCC_ICC | BPCC_PT, label_dest);
- tcg_out_nop(s);
- tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_next);
- tcg_out_cmp(s, al, bl, blconst);
- scond = tcg_cond_to_bcond[tcg_unsigned_cond(cond)];
- tcg_out_bpcc(s, scond, BPCC_ICC | BPCC_PT, label_dest);
- break;
- }
- tcg_out_nop(s);
-
- tcg_out_label(s, label_next, s->code_ptr);
-}
-#endif
-
-static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
- TCGArg c1, TCGArg c2, int c2const)
+static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg c1, int32_t c2, int c2const)
{
/* For 32-bit comparisons, we can play games with ADDX/SUBX. */
switch (cond) {
@@ -702,7 +685,7 @@
swap the operands on GTU/LEU. There's no benefit to loading
the constant into a temporary register. */
if (!c2const || c2 == 0) {
- TCGArg t = c1;
+ TCGReg t = c1;
c1 = c2;
c2 = t;
c2const = 0;
@@ -726,9 +709,8 @@
}
}
-#if TCG_TARGET_REG_BITS == 64
-static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
- TCGArg c1, TCGArg c2, int c2const)
+static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg c1, int32_t c2, int c2const)
{
/* For 64-bit signed comparisons vs zero, we can avoid the compare
if the input does not overlap the output. */
@@ -741,54 +723,12 @@
tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
}
}
-#else
-static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
- TCGArg al, TCGArg ah,
- TCGArg bl, int blconst,
- TCGArg bh, int bhconst)
+
+static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh,
+ TCGReg al, TCGReg ah, int32_t bl, int blconst,
+ int32_t bh, int bhconst, int opl, int oph)
{
- int tmp = TCG_REG_T1;
-
- /* Note that the low parts are fully consumed before tmp is set. */
- if (ret != ah && (bhconst || ret != bh)) {
- tmp = ret;
- }
-
- switch (cond) {
- case TCG_COND_EQ:
- case TCG_COND_NE:
- if (bl == 0 && bh == 0) {
- if (cond == TCG_COND_EQ) {
- tcg_out_arith(s, TCG_REG_G0, al, ah, ARITH_ORCC);
- tcg_out_movi(s, TCG_TYPE_I32, ret, 1);
- } else {
- tcg_out_arith(s, ret, al, ah, ARITH_ORCC);
- }
- } else {
- tcg_out_setcond_i32(s, cond, tmp, al, bl, blconst);
- tcg_out_cmp(s, ah, bh, bhconst);
- tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
- }
- tcg_out_movcc(s, TCG_COND_NE, MOVCC_ICC, ret, cond == TCG_COND_NE, 1);
- break;
-
- default:
- /* <= : ah < bh | (ah == bh && al <= bl) */
- tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), tmp, al, bl, blconst);
- tcg_out_cmp(s, ah, bh, bhconst);
- tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
- tcg_out_movcc(s, TCG_COND_NE, MOVCC_ICC, ret, 0, 1);
- tcg_out_movcc(s, tcg_high_cond(cond), MOVCC_ICC, ret, 1, 1);
- break;
- }
-}
-#endif
-
-static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
- TCGArg al, TCGArg ah, TCGArg bl, int blconst,
- TCGArg bh, int bhconst, int opl, int oph)
-{
- TCGArg tmp = TCG_REG_T1;
+ TCGReg tmp = TCG_REG_T1;
/* Note that the low parts are fully consumed before tmp is set. */
if (rl != ah && (bhconst || rl != bh)) {
@@ -800,7 +740,7 @@
tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
}
-static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
+static void tcg_out_calli(TCGContext *s, uintptr_t dest)
{
intptr_t disp = dest - (uintptr_t)s->code_ptr;
@@ -857,8 +797,13 @@
}
qemu_ld_trampoline[i] = tramp;
- /* Find the retaddr argument register. */
- ra = TCG_REG_O3 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
+ if (SPARC64 || TARGET_LONG_BITS == 32) {
+ ra = TCG_REG_O3;
+ } else {
+ /* Install the high part of the address. */
+ tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
+ ra = TCG_REG_O4;
+ }
/* Set the retaddr operand. */
tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
@@ -882,12 +827,28 @@
}
qemu_st_trampoline[i] = tramp;
- /* Find the retaddr argument. For 32-bit, this may be past the
- last argument register, and need passing on the stack. */
- ra = (TCG_REG_O4
- + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)
- + (TCG_TARGET_REG_BITS == 32 && (i & MO_SIZE) == MO_64));
-
+ if (SPARC64) {
+ ra = TCG_REG_O4;
+ } else {
+ ra = TCG_REG_O1;
+ if (TARGET_LONG_BITS == 64) {
+ /* Install the high part of the address. */
+ tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
+ ra += 2;
+ } else {
+ ra += 1;
+ }
+ if ((i & MO_SIZE) == MO_64) {
+ /* Install the high part of the data. */
+ tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
+ ra += 2;
+ } else {
+ ra += 1;
+ }
+ /* Skip the mem_index argument. */
+ ra += 1;
+ }
+
/* Set the retaddr operand. */
if (ra >= TCG_REG_O6) {
tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
@@ -956,25 +917,16 @@
The result of the TLB comparison is in %[ix]cc. The sanitized address
is in the returned register, maybe %o0. The TLB addend is in %o1. */
-static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
- int mem_index, TCGMemOp s_bits, int which)
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
+ TCGMemOp s_bits, int which)
{
const TCGReg r0 = TCG_REG_O0;
const TCGReg r1 = TCG_REG_O1;
const TCGReg r2 = TCG_REG_O2;
- TCGReg addr = addrlo;
int tlb_ofs;
- if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
- /* Assemble the 64-bit address in R0. */
- tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
- tcg_out_arithi(s, r1, addrhi, 32, SHIFT_SLLX);
- tcg_out_arith(s, r0, r0, r1, ARITH_OR);
- addr = r0;
- }
-
/* Shift the page number down. */
- tcg_out_arithi(s, r1, addrlo, TARGET_PAGE_BITS, SHIFT_SRL);
+ tcg_out_arithi(s, r1, addr, TARGET_PAGE_BITS, SHIFT_SRL);
/* Mask out the page offset, except for the required alignment. */
tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
@@ -994,8 +946,11 @@
/* Find a base address that can load both tlb comparator and addend. */
tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
- if (!check_fit_tl(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
- tcg_out_addi(s, r1, tlb_ofs & ~0x3ff);
+ if (!check_fit_ptr(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
+ if (tlb_ofs & ~0x3ff) {
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, tlb_ofs & ~0x3ff);
+ tcg_out_arith(s, r1, r1, TCG_REG_T1, ARITH_ADD);
+ }
tlb_ofs &= 0x3ff;
}
@@ -1007,11 +962,11 @@
tcg_out_cmp(s, r0, r2, 0);
/* If the guest address must be zero-extended, do so now. */
- if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
- tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
+ if (SPARC64 && TARGET_LONG_BITS == 32) {
+ tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
return r0;
}
- return addrlo;
+ return addr;
}
#endif /* CONFIG_SOFTMMU */
@@ -1044,78 +999,37 @@
[MO_LEQ] = STX_LE,
};
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
+static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
+ TCGMemOp memop, int memi, bool is_64)
{
- TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
- TCGMemOp memop, s_bits;
-#if defined(CONFIG_SOFTMMU)
+#ifdef CONFIG_SOFTMMU
+ TCGMemOp s_bits = memop & MO_SIZE;
TCGReg addrz, param;
uintptr_t func;
- int memi;
- uint32_t *label_ptr[2];
-#endif
+ uint32_t *label_ptr;
- datalo = *args++;
- datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
- addrlo = *args++;
- addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
- memop = *args++;
- s_bits = memop & MO_SIZE;
-
-#if defined(CONFIG_SOFTMMU)
- memi = *args++;
- addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
+ addrz = tcg_out_tlb_load(s, addr, memi, s_bits,
offsetof(CPUTLBEntry, addr_read));
- if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
- int reg64;
+ /* The fast path is exactly one insn. Thus we can perform the
+ entire TLB Hit in the (annulled) delay slot of the branch
+ over the TLB Miss case. */
- /* bne,pn %[xi]cc, label0 */
- label_ptr[0] = (uint32_t *)s->code_ptr;
- tcg_out_bpcc0(s, COND_NE, BPCC_PN
- | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
- tcg_out_nop(s);
-
- /* TLB Hit. */
- /* Load all 64-bits into an O/G register. */
- reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
- tcg_out_ldst_rr(s, reg64, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
-
- /* Move the two 32-bit pieces into the destination registers. */
- tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
- if (reg64 != datalo) {
- tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
- }
-
- /* b,a,pt label1 */
- label_ptr[1] = (uint32_t *)s->code_ptr;
- tcg_out_bpcc0(s, COND_A, BPCC_A | BPCC_PT, 0);
- } else {
- /* The fast path is exactly one insn. Thus we can perform the
- entire TLB Hit in the (annulled) delay slot of the branch
- over the TLB Miss case. */
-
- /* beq,a,pt %[xi]cc, label0 */
- label_ptr[0] = NULL;
- label_ptr[1] = (uint32_t *)s->code_ptr;
- tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
- | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
- /* delay slot */
- tcg_out_ldst_rr(s, datalo, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
- }
+ /* beq,a,pt %[xi]cc, label0 */
+ label_ptr = (uint32_t *)s->code_ptr;
+ tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
+ | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
+ /* delay slot */
+ tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
/* TLB Miss. */
- if (label_ptr[0]) {
- *label_ptr[0] |= INSN_OFF19((unsigned long)s->code_ptr -
- (unsigned long)label_ptr[0]);
- }
-
param = TCG_REG_O1;
- if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
+ if (!SPARC64 && TARGET_LONG_BITS == 64) {
+ /* Skip the high-part; we'll perform the extract in the trampoline. */
+ param++;
}
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
+ tcg_out_mov(s, TCG_TYPE_REG, param++, addr);
/* We use the helpers to extend SB and SW data, leaving the case
of SL needing explicit extending below. */
@@ -1129,81 +1043,54 @@
/* delay slot */
tcg_out_movi(s, TCG_TYPE_I32, param, memi);
- switch (memop & ~MO_BSWAP) {
- case MO_SL:
- tcg_out_arithi(s, datalo, TCG_REG_O0, 0, SHIFT_SRA);
- break;
- case MO_Q:
- if (TCG_TARGET_REG_BITS == 32) {
- tcg_out_mov(s, TCG_TYPE_REG, datahi, TCG_REG_O0);
- tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O1);
- break;
- }
- /* FALLTHRU */
- default:
- /* mov */
- tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O0);
- break;
- }
-
- *label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
- (unsigned long)label_ptr[1]);
-#else
- if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
- tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
- addrlo = TCG_REG_T1;
- }
- if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
- int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
-
- tcg_out_ldst_rr(s, reg64, addrlo,
- (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
- qemu_ld_opc[memop]);
-
- tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
- if (reg64 != datalo) {
- tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
+ /* Recall that all of the helpers return 64-bit results.
+ Which complicates things for sparcv8plus. */
+ if (SPARC64) {
+ /* We let the helper sign-extend SB and SW, but leave SL for here. */
+ if (is_64 && (memop & ~MO_BSWAP) == MO_SL) {
+ tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
+ } else {
+ tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
}
} else {
- tcg_out_ldst_rr(s, datalo, addrlo,
- (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
- qemu_ld_opc[memop]);
+ if (s_bits == MO_64) {
+ tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX);
+ tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL);
+ tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR);
+ } else if (is_64) {
+ /* Re-extend from 32-bit rather than reassembling when we
+ know the high register must be an extension. */
+ tcg_out_arithi(s, data, TCG_REG_O1, 0,
+ memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL);
+ } else {
+ tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1);
+ }
}
+
+ *label_ptr |= INSN_OFF19((uintptr_t)s->code_ptr - (uintptr_t)label_ptr);
+#else
+ if (SPARC64 && TARGET_LONG_BITS == 32) {
+ tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
+ addr = TCG_REG_T1;
+ }
+ tcg_out_ldst_rr(s, data, addr,
+ (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
+ qemu_ld_opc[memop]);
#endif /* CONFIG_SOFTMMU */
}
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
+static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
+ TCGMemOp memop, int memi)
{
- TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
- TCGMemOp memop, s_bits;
-#if defined(CONFIG_SOFTMMU)
- TCGReg addrz, datafull, param;
+#ifdef CONFIG_SOFTMMU
+ TCGMemOp s_bits = memop & MO_SIZE;
+ TCGReg addrz, param;
uintptr_t func;
- int memi;
uint32_t *label_ptr;
-#endif
- datalo = *args++;
- datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
- addrlo = *args++;
- addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
- memop = *args++;
- s_bits = memop & MO_SIZE;
-
-#if defined(CONFIG_SOFTMMU)
- memi = *args++;
- addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
+ addrz = tcg_out_tlb_load(s, addr, memi, s_bits,
offsetof(CPUTLBEntry, addr_write));
- datafull = datalo;
- if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
- /* Reconstruct the full 64-bit value. */
- tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
- tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
- tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
- datafull = TCG_REG_O2;
- }
-
/* The fast path is exactly one insn. Thus we can perform the entire
TLB Hit in the (annulled) delay slot of the branch over TLB Miss. */
/* beq,a,pt %[xi]cc, label0 */
@@ -1211,19 +1098,21 @@
tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
| (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
/* delay slot */
- tcg_out_ldst_rr(s, datafull, addrz, TCG_REG_O1, qemu_st_opc[memop]);
+ tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1, qemu_st_opc[memop]);
/* TLB Miss. */
param = TCG_REG_O1;
- if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
+ if (!SPARC64 && TARGET_LONG_BITS == 64) {
+ /* Skip the high-part; we'll perform the extract in the trampoline. */
+ param++;
}
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
- if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
- tcg_out_mov(s, TCG_TYPE_REG, param++, datahi);
+ tcg_out_mov(s, TCG_TYPE_REG, param++, addr);
+ if (!SPARC64 && s_bits == MO_64) {
+ /* Skip the high-part; we'll perform the extract in the trampoline. */
+ param++;
}
- tcg_out_mov(s, TCG_TYPE_REG, param++, datalo);
+ tcg_out_mov(s, TCG_TYPE_REG, param++, data);
func = qemu_st_trampoline[memop];
assert(func != 0);
@@ -1231,106 +1120,100 @@
/* delay slot */
tcg_out_movi(s, TCG_TYPE_REG, param, memi);
- *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
- (unsigned long)label_ptr);
+ *label_ptr |= INSN_OFF19((uintptr_t)s->code_ptr - (uintptr_t)label_ptr);
#else
- if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
- tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
- addrlo = TCG_REG_T1;
+ if (SPARC64 && TARGET_LONG_BITS == 32) {
+ tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
+ addr = TCG_REG_T1;
}
- if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
- tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
- tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
- tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
- datalo = TCG_REG_O2;
- }
- tcg_out_ldst_rr(s, datalo, addrlo,
+ tcg_out_ldst_rr(s, data, addr,
(GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
qemu_st_opc[memop]);
#endif /* CONFIG_SOFTMMU */
}
-static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
- const int *const_args)
+static void tcg_out_op(TCGContext *s, TCGOpcode opc,
+ const TCGArg args[TCG_MAX_OP_ARGS],
+ const int const_args[TCG_MAX_OP_ARGS])
{
- int c;
+ TCGArg a0, a1, a2;
+ int c, c2;
+
+ /* Hoist the loads of the most common arguments. */
+ a0 = args[0];
+ a1 = args[1];
+ a2 = args[2];
+ c2 = const_args[2];
switch (opc) {
case INDEX_op_exit_tb:
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
- tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, JMPL);
- tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
- INSN_RS2(TCG_REG_G0));
+ if (check_fit_ptr(a0, 13)) {
+ tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
+ tcg_out_movi_imm13(s, TCG_REG_O0, a0);
+ } else {
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, a0 & ~0x3ff);
+ tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
+ tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, a0 & 0x3ff, ARITH_OR);
+ }
break;
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
/* direct jump method */
uint32_t old_insn = *(uint32_t *)s->code_ptr;
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
+ s->tb_jmp_offset[a0] = s->code_ptr - s->code_buf;
/* Make sure to preserve links during retranslation. */
tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
} else {
/* indirect jump method */
- tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + args[0]));
+ tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + a0));
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
}
tcg_out_nop(s);
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+ s->tb_next_offset[a0] = s->code_ptr - s->code_buf;
break;
case INDEX_op_call:
if (const_args[0]) {
- tcg_out_calli(s, args[0]);
+ tcg_out_calli(s, a0);
} else {
- tcg_out_arithi(s, TCG_REG_O7, args[0], 0, JMPL);
+ tcg_out_arithi(s, TCG_REG_O7, a0, 0, JMPL);
}
/* delay slot */
tcg_out_nop(s);
break;
case INDEX_op_br:
- tcg_out_bpcc(s, COND_A, BPCC_PT, args[0]);
+ tcg_out_bpcc(s, COND_A, BPCC_PT, a0);
tcg_out_nop(s);
break;
- case INDEX_op_movi_i32:
- tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
- break;
-#if TCG_TARGET_REG_BITS == 64
#define OP_32_64(x) \
glue(glue(case INDEX_op_, x), _i32): \
glue(glue(case INDEX_op_, x), _i64)
-#else
-#define OP_32_64(x) \
- glue(glue(case INDEX_op_, x), _i32)
-#endif
+
OP_32_64(ld8u):
- tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
+ tcg_out_ldst(s, a0, a1, a2, LDUB);
break;
OP_32_64(ld8s):
- tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
+ tcg_out_ldst(s, a0, a1, a2, LDSB);
break;
OP_32_64(ld16u):
- tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
+ tcg_out_ldst(s, a0, a1, a2, LDUH);
break;
OP_32_64(ld16s):
- tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
+ tcg_out_ldst(s, a0, a1, a2, LDSH);
break;
case INDEX_op_ld_i32:
-#if TCG_TARGET_REG_BITS == 64
case INDEX_op_ld32u_i64:
-#endif
- tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
+ tcg_out_ldst(s, a0, a1, a2, LDUW);
break;
OP_32_64(st8):
- tcg_out_ldst(s, args[0], args[1], args[2], STB);
+ tcg_out_ldst(s, a0, a1, a2, STB);
break;
OP_32_64(st16):
- tcg_out_ldst(s, args[0], args[1], args[2], STH);
+ tcg_out_ldst(s, a0, a1, a2, STH);
break;
case INDEX_op_st_i32:
-#if TCG_TARGET_REG_BITS == 64
case INDEX_op_st32_i64:
-#endif
- tcg_out_ldst(s, args[0], args[1], args[2], STW);
+ tcg_out_ldst(s, a0, a1, a2, STW);
break;
OP_32_64(add):
c = ARITH_ADD;
@@ -1357,7 +1240,7 @@
c = SHIFT_SLL;
do_shift32:
/* Limit immediate shift count lest we create an illegal insn. */
- tcg_out_arithc(s, args[0], args[1], args[2] & 31, const_args[2], c);
+ tcg_out_arithc(s, a0, a1, a2 & 31, c2, c);
break;
case INDEX_op_shr_i32:
c = SHIFT_SRL;
@@ -1377,85 +1260,71 @@
goto gen_arith1;
case INDEX_op_div_i32:
- tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 0);
+ tcg_out_div32(s, a0, a1, a2, c2, 0);
break;
case INDEX_op_divu_i32:
- tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
+ tcg_out_div32(s, a0, a1, a2, c2, 1);
break;
case INDEX_op_brcond_i32:
- tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
- args[3]);
+ tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], args[3]);
break;
case INDEX_op_setcond_i32:
- tcg_out_setcond_i32(s, args[3], args[0], args[1],
- args[2], const_args[2]);
+ tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2);
break;
case INDEX_op_movcond_i32:
- tcg_out_movcond_i32(s, args[5], args[0], args[1],
- args[2], const_args[2], args[3], const_args[3]);
+ tcg_out_movcond_i32(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
break;
-#if TCG_TARGET_REG_BITS == 32
- case INDEX_op_brcond2_i32:
- tcg_out_brcond2_i32(s, args[4], args[0], args[1],
- args[2], const_args[2],
- args[3], const_args[3], args[5]);
- break;
- case INDEX_op_setcond2_i32:
- tcg_out_setcond2_i32(s, args[5], args[0], args[1], args[2],
- args[3], const_args[3],
- args[4], const_args[4]);
- break;
-#endif
-
case INDEX_op_add2_i32:
- tcg_out_addsub2(s, args[0], args[1], args[2], args[3],
- args[4], const_args[4], args[5], const_args[5],
- ARITH_ADDCC, ARITH_ADDX);
+ tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], const_args[4],
+ args[5], const_args[5], ARITH_ADDCC, ARITH_ADDX);
break;
case INDEX_op_sub2_i32:
- tcg_out_addsub2(s, args[0], args[1], args[2], args[3],
- args[4], const_args[4], args[5], const_args[5],
- ARITH_SUBCC, ARITH_SUBX);
+ tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], const_args[4],
+ args[5], const_args[5], ARITH_SUBCC, ARITH_SUBX);
break;
case INDEX_op_mulu2_i32:
- tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
- ARITH_UMUL);
- tcg_out_rdy(s, args[1]);
+ c = ARITH_UMUL;
+ goto do_mul2;
+ case INDEX_op_muls2_i32:
+ c = ARITH_SMUL;
+ do_mul2:
+ /* The 32-bit multiply insns produce a full 64-bit result. If the
+ destination register can hold it, we can avoid the slower RDY. */
+ tcg_out_arithc(s, a0, a2, args[3], const_args[3], c);
+ if (SPARC64 || a0 <= TCG_REG_O7) {
+ tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
+ } else {
+ tcg_out_rdy(s, a1);
+ }
break;
case INDEX_op_qemu_ld_i32:
- tcg_out_qemu_ld(s, args, 0);
+ tcg_out_qemu_ld(s, a0, a1, a2, args[3], false);
break;
case INDEX_op_qemu_ld_i64:
- tcg_out_qemu_ld(s, args, 1);
+ tcg_out_qemu_ld(s, a0, a1, a2, args[3], true);
break;
case INDEX_op_qemu_st_i32:
- tcg_out_qemu_st(s, args, 0);
- break;
case INDEX_op_qemu_st_i64:
- tcg_out_qemu_st(s, args, 1);
+ tcg_out_qemu_st(s, a0, a1, a2, args[3]);
break;
-#if TCG_TARGET_REG_BITS == 64
- case INDEX_op_movi_i64:
- tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
- break;
case INDEX_op_ld32s_i64:
- tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
+ tcg_out_ldst(s, a0, a1, a2, LDSW);
break;
case INDEX_op_ld_i64:
- tcg_out_ldst(s, args[0], args[1], args[2], LDX);
+ tcg_out_ldst(s, a0, a1, a2, LDX);
break;
case INDEX_op_st_i64:
- tcg_out_ldst(s, args[0], args[1], args[2], STX);
+ tcg_out_ldst(s, a0, a1, a2, STX);
break;
case INDEX_op_shl_i64:
c = SHIFT_SLLX;
do_shift64:
/* Limit immediate shift count lest we create an illegal insn. */
- tcg_out_arithc(s, args[0], args[1], args[2] & 63, const_args[2], c);
+ tcg_out_arithc(s, a0, a1, a2 & 63, c2, c);
break;
case INDEX_op_shr_i64:
c = SHIFT_SRLX;
@@ -1473,35 +1342,44 @@
c = ARITH_UDIVX;
goto gen_arith;
case INDEX_op_ext32s_i64:
- tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
+ tcg_out_arithi(s, a0, a1, 0, SHIFT_SRA);
break;
case INDEX_op_ext32u_i64:
- tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
+ tcg_out_arithi(s, a0, a1, 0, SHIFT_SRL);
+ break;
+ case INDEX_op_trunc_shr_i32:
+ if (a2 == 0) {
+ tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
+ } else {
+ tcg_out_arithi(s, a0, a1, a2, SHIFT_SRLX);
+ }
break;
case INDEX_op_brcond_i64:
- tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
- args[3]);
+ tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], args[3]);
break;
case INDEX_op_setcond_i64:
- tcg_out_setcond_i64(s, args[3], args[0], args[1],
- args[2], const_args[2]);
+ tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2);
break;
case INDEX_op_movcond_i64:
- tcg_out_movcond_i64(s, args[5], args[0], args[1],
- args[2], const_args[2], args[3], const_args[3]);
+ tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
break;
-#endif
+
gen_arith:
- tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
+ tcg_out_arithc(s, a0, a1, a2, c2, c);
break;
gen_arith1:
- tcg_out_arithc(s, args[0], TCG_REG_G0, args[1], const_args[1], c);
+ tcg_out_arithc(s, a0, TCG_REG_G0, a1, const_args[1], c);
break;
+ case INDEX_op_mov_i64:
+ case INDEX_op_mov_i32:
+ case INDEX_op_movi_i64:
+ case INDEX_op_movi_i32:
+ /* Always implemented with tcg_out_mov/i, never with tcg_out_op. */
default:
- fprintf(stderr, "unknown opcode 0x%x\n", opc);
+ /* Opcode not implemented. */
tcg_abort();
}
}
@@ -1545,72 +1423,55 @@
{ INDEX_op_setcond_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_movcond_i32, { "r", "rZ", "rJ", "rI", "0" } },
-#if TCG_TARGET_REG_BITS == 32
- { INDEX_op_brcond2_i32, { "rZ", "rZ", "rJ", "rJ" } },
- { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rJ", "rJ" } },
-#endif
-
{ INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
{ INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
{ INDEX_op_mulu2_i32, { "r", "r", "rZ", "rJ" } },
+ { INDEX_op_muls2_i32, { "r", "r", "rZ", "rJ" } },
-#if TCG_TARGET_REG_BITS == 64
- { INDEX_op_mov_i64, { "r", "r" } },
- { INDEX_op_movi_i64, { "r" } },
- { INDEX_op_ld8u_i64, { "r", "r" } },
- { INDEX_op_ld8s_i64, { "r", "r" } },
- { INDEX_op_ld16u_i64, { "r", "r" } },
- { INDEX_op_ld16s_i64, { "r", "r" } },
- { INDEX_op_ld32u_i64, { "r", "r" } },
- { INDEX_op_ld32s_i64, { "r", "r" } },
- { INDEX_op_ld_i64, { "r", "r" } },
- { INDEX_op_st8_i64, { "rZ", "r" } },
- { INDEX_op_st16_i64, { "rZ", "r" } },
- { INDEX_op_st32_i64, { "rZ", "r" } },
- { INDEX_op_st_i64, { "rZ", "r" } },
+ { INDEX_op_mov_i64, { "R", "R" } },
+ { INDEX_op_movi_i64, { "R" } },
+ { INDEX_op_ld8u_i64, { "R", "r" } },
+ { INDEX_op_ld8s_i64, { "R", "r" } },
+ { INDEX_op_ld16u_i64, { "R", "r" } },
+ { INDEX_op_ld16s_i64, { "R", "r" } },
+ { INDEX_op_ld32u_i64, { "R", "r" } },
+ { INDEX_op_ld32s_i64, { "R", "r" } },
+ { INDEX_op_ld_i64, { "R", "r" } },
+ { INDEX_op_st8_i64, { "RZ", "r" } },
+ { INDEX_op_st16_i64, { "RZ", "r" } },
+ { INDEX_op_st32_i64, { "RZ", "r" } },
+ { INDEX_op_st_i64, { "RZ", "r" } },
- { INDEX_op_add_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_mul_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_div_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_divu_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_sub_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_and_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_andc_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_or_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_orc_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_xor_i64, { "r", "rZ", "rJ" } },
+ { INDEX_op_add_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_mul_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_div_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_divu_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_sub_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_and_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_andc_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_or_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_orc_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_xor_i64, { "R", "RZ", "RJ" } },
- { INDEX_op_shl_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_shr_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_sar_i64, { "r", "rZ", "rJ" } },
+ { INDEX_op_shl_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_shr_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_sar_i64, { "R", "RZ", "RJ" } },
- { INDEX_op_neg_i64, { "r", "rJ" } },
- { INDEX_op_not_i64, { "r", "rJ" } },
+ { INDEX_op_neg_i64, { "R", "RJ" } },
+ { INDEX_op_not_i64, { "R", "RJ" } },
- { INDEX_op_ext32s_i64, { "r", "r" } },
- { INDEX_op_ext32u_i64, { "r", "r" } },
+ { INDEX_op_ext32s_i64, { "R", "r" } },
+ { INDEX_op_ext32u_i64, { "R", "r" } },
+ { INDEX_op_trunc_shr_i32, { "r", "R" } },
- { INDEX_op_brcond_i64, { "rZ", "rJ" } },
- { INDEX_op_setcond_i64, { "r", "rZ", "rJ" } },
- { INDEX_op_movcond_i64, { "r", "rZ", "rJ", "rI", "0" } },
-#endif
+ { INDEX_op_brcond_i64, { "RZ", "RJ" } },
+ { INDEX_op_setcond_i64, { "R", "RZ", "RJ" } },
+ { INDEX_op_movcond_i64, { "R", "RZ", "RJ", "RI", "0" } },
-#if TCG_TARGET_REG_BITS == 64
- { INDEX_op_qemu_ld_i32, { "r", "L" } },
- { INDEX_op_qemu_ld_i64, { "r", "L" } },
- { INDEX_op_qemu_st_i32, { "L", "L" } },
- { INDEX_op_qemu_st_i64, { "L", "L" } },
-#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
- { INDEX_op_qemu_ld_i32, { "r", "L" } },
- { INDEX_op_qemu_ld_i64, { "r", "r", "L" } },
- { INDEX_op_qemu_st_i32, { "L", "L" } },
- { INDEX_op_qemu_st_i64, { "L", "L", "L" } },
-#else
- { INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
- { INDEX_op_qemu_ld_i64, { "L", "L", "L", "L" } },
- { INDEX_op_qemu_st_i32, { "L", "L", "L" } },
- { INDEX_op_qemu_st_i64, { "L", "L", "L", "L" } },
-#endif
+ { INDEX_op_qemu_ld_i32, { "r", "A" } },
+ { INDEX_op_qemu_ld_i64, { "R", "A" } },
+ { INDEX_op_qemu_st_i32, { "sZ", "A" } },
+ { INDEX_op_qemu_st_i64, { "SZ", "A" } },
{ -1 },
};
@@ -1618,9 +1479,8 @@
static void tcg_target_init(TCGContext *s)
{
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
-#if TCG_TARGET_REG_BITS == 64
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
-#endif
+ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, ALL_64);
+
tcg_regset_set32(tcg_target_call_clobber_regs, 0,
(1 << TCG_REG_G1) |
(1 << TCG_REG_G2) |
@@ -1650,7 +1510,7 @@
tcg_add_target_add_op_defs(sparc_op_defs);
}
-#if TCG_TARGET_REG_BITS == 64
+#if SPARC64
# define ELF_HOST_MACHINE EM_SPARCV9
#else
# define ELF_HOST_MACHINE EM_SPARC32PLUS
@@ -1660,7 +1520,7 @@
typedef struct {
DebugFrameCIE cie;
DebugFrameFDEHeader fde;
- uint8_t fde_def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
+ uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
uint8_t fde_win_save;
uint8_t fde_ret_save[3];
} DebugFrame;
@@ -1677,7 +1537,7 @@
.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
.fde_def_cfa = {
-#if TCG_TARGET_REG_BITS == 64
+#if SPARC64
12, 30, /* DW_CFA_def_cfa i6, 2047 */
(2047 & 0x7f) | 0x80, (2047 >> 7)
#else
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 4519c64..3a903db 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -24,13 +24,7 @@
#ifndef TCG_TARGET_SPARC
#define TCG_TARGET_SPARC 1
-#if UINTPTR_MAX == UINT32_MAX
-# define TCG_TARGET_REG_BITS 32
-#elif UINTPTR_MAX == UINT64_MAX
-# define TCG_TARGET_REG_BITS 64
-#else
-# error Unknown pointer size for tcg target
-#endif
+#define TCG_TARGET_REG_BITS 64
#define TCG_TARGET_NB_REGS 32
@@ -76,7 +70,7 @@
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_O6
-#if TCG_TARGET_REG_BITS == 64
+#ifdef __arch64__
#define TCG_TARGET_STACK_BIAS 2047
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET (128 + 6*8 + TCG_TARGET_STACK_BIAS)
@@ -86,7 +80,7 @@
#define TCG_TARGET_CALL_STACK_OFFSET (64 + 4 + 6*4)
#endif
-#if TCG_TARGET_REG_BITS == 64
+#ifdef __arch64__
#define TCG_TARGET_EXTEND_ARGS 1
#endif
@@ -112,11 +106,11 @@
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
-#define TCG_TARGET_HAS_muls2_i32 0
+#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
-#if TCG_TARGET_REG_BITS == 64
+#define TCG_TARGET_HAS_trunc_shr_i32 1
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 0
@@ -144,7 +138,6 @@
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
-#endif
#define TCG_TARGET_HAS_new_ldst 1
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 8d4ff7d..6dbbb38 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -1624,9 +1624,20 @@
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
}
-static inline void tcg_gen_trunc_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
+static inline void tcg_gen_trunc_shr_i64_i32(TCGv_i32 ret, TCGv_i64 arg,
+ unsigned int count)
{
- tcg_gen_mov_i32(ret, TCGV_LOW(arg));
+ tcg_debug_assert(count < 64);
+ if (count >= 32) {
+ tcg_gen_shri_i32(ret, TCGV_HIGH(arg), count - 32);
+ } else if (count == 0) {
+ tcg_gen_mov_i32(ret, TCGV_LOW(arg));
+ } else {
+ TCGv_i64 t = tcg_temp_new_i64();
+ tcg_gen_shri_i64(t, arg, count);
+ tcg_gen_mov_i32(ret, TCGV_LOW(t));
+ tcg_temp_free_i64(t);
+ }
}
static inline void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
@@ -1727,11 +1738,21 @@
}
}
-/* Note: we assume the target supports move between 32 and 64 bit
- registers. This will probably break MIPS64 targets. */
-static inline void tcg_gen_trunc_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
+static inline void tcg_gen_trunc_shr_i64_i32(TCGv_i32 ret, TCGv_i64 arg,
+ unsigned int count)
{
- tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg)));
+ tcg_debug_assert(count < 64);
+ if (TCG_TARGET_HAS_trunc_shr_i32) {
+ tcg_gen_op3i_i32(INDEX_op_trunc_shr_i32, ret,
+ MAKE_TCGV_I32(GET_TCGV_I64(arg)), count);
+ } else if (count == 0) {
+ tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg)));
+ } else {
+ TCGv_i64 t = tcg_temp_new_i64();
+ tcg_gen_shri_i64(t, arg, count);
+ tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(t)));
+ tcg_temp_free_i64(t);
+ }
}
/* Note: we assume the target supports move between 32 and 64 bit
@@ -2275,18 +2296,15 @@
tcg_gen_deposit_i64(dest, low, high, 32, 32);
}
+static inline void tcg_gen_trunc_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
+{
+ tcg_gen_trunc_shr_i64_i32(ret, arg, 0);
+}
+
static inline void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
{
-#if TCG_TARGET_REG_BITS == 32
- tcg_gen_mov_i32(lo, TCGV_LOW(arg));
- tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
-#else
- TCGv_i64 t0 = tcg_temp_new_i64();
- tcg_gen_trunc_i64_i32(lo, arg);
- tcg_gen_shri_i64(t0, arg, 32);
- tcg_gen_trunc_i64_i32(hi, t0);
- tcg_temp_free_i64(t0);
-#endif
+ tcg_gen_trunc_shr_i64_i32(lo, arg, 0);
+ tcg_gen_trunc_shr_i64_i32(hi, arg, 32);
}
static inline void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
@@ -2861,7 +2879,7 @@
#define tcg_gen_muls2_tl tcg_gen_muls2_i32
#endif
-#if TCG_TARGET_REG_BITS == 32
+#if UINTPTR_MAX == UINT32_MAX
# define tcg_gen_ld_ptr(R, A, O) \
tcg_gen_ld_i32(TCGV_PTR_TO_NAT(R), (A), (O))
# define tcg_gen_discard_ptr(A) \
@@ -2883,4 +2901,4 @@
tcg_gen_addi_i64(TCGV_PTR_TO_NAT(R), TCGV_PTR_TO_NAT(A), (B))
# define tcg_gen_ext_i32_ptr(R, A) \
tcg_gen_ext_i32_i64(TCGV_PTR_TO_NAT(R), (A))
-#endif /* TCG_TARGET_REG_BITS == 32 */
+#endif /* UINTPTR_MAX == UINT32_MAX */
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index d71707d..adb6ce1 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -147,6 +147,10 @@
DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64))
+DEF(trunc_shr_i32, 1, 1, 1,
+ IMPL(TCG_TARGET_HAS_trunc_shr_i32)
+ | (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0))
+
DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | IMPL64)
DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64))
DEF(ext16s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16s_i64))
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 21ce9fb..e71f7a0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -664,7 +664,36 @@
int nb_rets;
TCGArg *nparam;
-#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+#if defined(__sparc__) && !defined(__arch64__) \
+ && !defined(CONFIG_TCG_INTERPRETER)
+ /* We have 64-bit values in one register, but need to pass as two
+ separate parameters. Split them. */
+ int orig_sizemask = sizemask;
+ int orig_nargs = nargs;
+ TCGv_i64 retl, reth;
+
+ TCGV_UNUSED_I64(retl);
+ TCGV_UNUSED_I64(reth);
+ if (sizemask != 0) {
+ TCGArg *split_args = __builtin_alloca(sizeof(TCGArg) * nargs * 2);
+ for (i = real_args = 0; i < nargs; ++i) {
+ int is_64bit = sizemask & (1 << (i+1)*2);
+ if (is_64bit) {
+ TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
+ TCGv_i32 h = tcg_temp_new_i32();
+ TCGv_i32 l = tcg_temp_new_i32();
+ tcg_gen_extr_i64_i32(l, h, orig);
+ split_args[real_args++] = GET_TCGV_I32(h);
+ split_args[real_args++] = GET_TCGV_I32(l);
+ } else {
+ split_args[real_args++] = args[i];
+ }
+ }
+ nargs = real_args;
+ args = split_args;
+ sizemask = 0;
+ }
+#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
int is_64bit = sizemask & (1 << (i+1)*2);
int is_signed = sizemask & (2 << (i+1)*2);
@@ -684,8 +713,23 @@
*s->gen_opc_ptr++ = INDEX_op_call;
nparam = s->gen_opparam_ptr++;
if (ret != TCG_CALL_DUMMY_ARG) {
-#if TCG_TARGET_REG_BITS < 64
- if (sizemask & 1) {
+#if defined(__sparc__) && !defined(__arch64__) \
+ && !defined(CONFIG_TCG_INTERPRETER)
+ if (orig_sizemask & 1) {
+ /* The 32-bit ABI is going to return the 64-bit value in
+ the %o0/%o1 register pair. Prepare for this by using
+ two return temporaries, and reassemble below. */
+ retl = tcg_temp_new_i64();
+ reth = tcg_temp_new_i64();
+ *s->gen_opparam_ptr++ = GET_TCGV_I64(reth);
+ *s->gen_opparam_ptr++ = GET_TCGV_I64(retl);
+ nb_rets = 2;
+ } else {
+ *s->gen_opparam_ptr++ = ret;
+ nb_rets = 1;
+ }
+#else
+ if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
#ifdef HOST_WORDS_BIGENDIAN
*s->gen_opparam_ptr++ = ret + 1;
*s->gen_opparam_ptr++ = ret;
@@ -694,12 +738,11 @@
*s->gen_opparam_ptr++ = ret + 1;
#endif
nb_rets = 2;
- } else
-#endif
- {
+ } else {
*s->gen_opparam_ptr++ = ret;
nb_rets = 1;
}
+#endif
} else {
nb_rets = 0;
}
@@ -749,7 +792,29 @@
/* total parameters, needed to go backward in the instruction stream */
*s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
-#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+#if defined(__sparc__) && !defined(__arch64__) \
+ && !defined(CONFIG_TCG_INTERPRETER)
+ /* Free all of the parts we allocated above. */
+ for (i = real_args = 0; i < orig_nargs; ++i) {
+ int is_64bit = orig_sizemask & (1 << (i+1)*2);
+ if (is_64bit) {
+ TCGv_i32 h = MAKE_TCGV_I32(args[real_args++]);
+ TCGv_i32 l = MAKE_TCGV_I32(args[real_args++]);
+ tcg_temp_free_i32(h);
+ tcg_temp_free_i32(l);
+ } else {
+ real_args++;
+ }
+ }
+ if (orig_sizemask & 1) {
+ /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
+ Note that describing these as TCGv_i64 eliminates an unnecessary
+ zero-extension that tcg_gen_concat_i32_i64 would create. */
+ tcg_gen_concat32_i64(MAKE_TCGV_I64(ret), retl, reth);
+ tcg_temp_free_i64(retl);
+ tcg_temp_free_i64(reth);
+ }
+#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
int is_64bit = sizemask & (1 << (i+1)*2);
if (!is_64bit) {
@@ -2411,6 +2476,7 @@
ts = &s->temps[arg];
reg = tcg_target_call_oarg_regs[i];
assert(s->reg_to_temp[reg] == -1);
+
if (ts->fixed_reg) {
if (ts->reg != reg) {
tcg_out_mov(s, ts->type, ts->reg, reg);
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 0bb6677..a6a2d06 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -66,6 +66,7 @@
#if TCG_TARGET_REG_BITS == 32
/* Turn some undef macros into false macros. */
+#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_div2_i64 0
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index f43492c..37719e8 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -82,6 +82,7 @@
#define TCG_TARGET_HAS_mulsh_i32 0
#if TCG_TARGET_REG_BITS == 64
+#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
diff --git a/tests/.gitignore b/tests/.gitignore
index 9ba9d96..c71c110 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -7,20 +7,28 @@
check-qom-interface
test-aio
test-bitops
-test-throttle
+test-coroutine
test-cutils
test-hbitmap
test-int128
test-iov
test-mul64
+test-opts-visitor
test-qapi-types.[ch]
test-qapi-visit.[ch]
test-qdev-global-props
-test-qmp-commands.h
test-qmp-commands
+test-qmp-commands.h
test-qmp-input-strict
+test-qmp-input-visitor
test-qmp-marshal.c
+test-qmp-output-visitor
+test-rfifolock
+test-string-input-visitor
+test-string-output-visitor
test-thread-pool
+test-throttle
+test-visitor-serialization
test-vmstate
test-x86-cpuid
test-xbzrle
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index 59a34f7..8cb61fd 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -50,15 +50,7 @@
result = self.vm.qmp('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
- completed = False
- while not completed:
- for event in self.vm.get_qmp_events(wait=True):
- if event['event'] == 'BLOCK_JOB_COMPLETED':
- self.assert_qmp(event, 'data/type', 'stream')
- self.assert_qmp(event, 'data/device', 'drive0')
- self.assert_qmp(event, 'data/offset', self.image_len)
- self.assert_qmp(event, 'data/len', self.image_len)
- completed = True
+ self.wait_until_completed()
self.assert_no_active_block_jobs()
self.vm.shutdown()
@@ -89,15 +81,7 @@
self.assert_qmp(result, 'return', {})
self.vm.resume_drive('drive0')
- completed = False
- while not completed:
- for event in self.vm.get_qmp_events(wait=True):
- if event['event'] == 'BLOCK_JOB_COMPLETED':
- self.assert_qmp(event, 'data/type', 'stream')
- self.assert_qmp(event, 'data/device', 'drive0')
- self.assert_qmp(event, 'data/offset', self.image_len)
- self.assert_qmp(event, 'data/len', self.image_len)
- completed = True
+ self.wait_until_completed()
self.assert_no_active_block_jobs()
self.vm.shutdown()
@@ -112,15 +96,7 @@
result = self.vm.qmp('block-stream', device='drive0', base=mid_img)
self.assert_qmp(result, 'return', {})
- completed = False
- while not completed:
- for event in self.vm.get_qmp_events(wait=True):
- if event['event'] == 'BLOCK_JOB_COMPLETED':
- self.assert_qmp(event, 'data/type', 'stream')
- self.assert_qmp(event, 'data/device', 'drive0')
- self.assert_qmp(event, 'data/offset', self.image_len)
- self.assert_qmp(event, 'data/len', self.image_len)
- completed = True
+ self.wait_until_completed()
self.assert_no_active_block_jobs()
self.vm.shutdown()
@@ -152,15 +128,7 @@
result = self.vm.qmp('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
- completed = False
- while not completed:
- for event in self.vm.get_qmp_events(wait=True):
- if event['event'] == 'BLOCK_JOB_COMPLETED':
- self.assert_qmp(event, 'data/type', 'stream')
- self.assert_qmp(event, 'data/device', 'drive0')
- self.assert_qmp(event, 'data/offset', self.image_len)
- self.assert_qmp(event, 'data/len', self.image_len)
- completed = True
+ self.wait_until_completed()
self.assert_no_active_block_jobs()
self.vm.shutdown()
@@ -442,15 +410,7 @@
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
self.assert_qmp(result, 'return', {})
- completed = False
- while not completed:
- for event in self.vm.get_qmp_events(wait=True):
- if event['event'] == 'BLOCK_JOB_COMPLETED':
- self.assert_qmp(event, 'data/type', 'stream')
- self.assert_qmp(event, 'data/device', 'drive0')
- self.assert_qmp(event, 'data/offset', self.image_len)
- self.assert_qmp(event, 'data/len', self.image_len)
- completed = True
+ self.wait_until_completed()
self.assert_no_active_block_jobs()
diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
index 6389342..54e4bd0 100755
--- a/tests/qemu-iotests/056
+++ b/tests/qemu-iotests/056
@@ -57,14 +57,7 @@
format=iotests.imgfmt, target=target_img)
self.assert_qmp(result, 'return', {})
- # Custom completed check as we are not copying all data.
- completed = False
- while not completed:
- for event in self.vm.get_qmp_events(wait=True):
- if event['event'] == 'BLOCK_JOB_COMPLETED':
- self.assert_qmp(event, 'data/device', 'drive0')
- self.assert_qmp_absent(event, 'data/error')
- completed = True
+ self.wait_until_completed(check_offset=False)
self.assert_no_active_block_jobs()
self.vm.shutdown()
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index e4fa9af..f6c437c 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -257,7 +257,7 @@
self.assert_no_active_block_jobs()
return result
- def wait_until_completed(self, drive='drive0'):
+ def wait_until_completed(self, drive='drive0', check_offset=True):
'''Wait for a block job to finish, returning the event'''
completed = False
while not completed:
@@ -265,7 +265,8 @@
if event['event'] == 'BLOCK_JOB_COMPLETED':
self.assert_qmp(event, 'data/device', drive)
self.assert_qmp_absent(event, 'data/error')
- self.assert_qmp(event, 'data/offset', self.image_len)
+ if check_offset:
+ self.assert_qmp(event, 'data/offset', self.image_len)
self.assert_qmp(event, 'data/len', self.image_len)
completed = True
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 38b5e95..f03353b 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -153,7 +153,7 @@
/* TODO when generator bug is fixed, add 'integer': 41 */
visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
qapi_free_UserDefFlatUnion(tmp);
}
@@ -167,7 +167,7 @@
v = validate_test_init(data, "42");
visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
qapi_free_UserDefAnonUnion(tmp);
}
@@ -240,7 +240,7 @@
v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
qapi_free_UserDefFlatUnion(tmp);
}
@@ -254,7 +254,7 @@
v = validate_test_init(data, "3.14");
visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
qapi_free_UserDefAnonUnion(tmp);
}
diff --git a/trace-events b/trace-events
index 6ecaab2..a5218ba 100644
--- a/trace-events
+++ b/trace-events
@@ -1243,3 +1243,7 @@
# hw/pci/pci_host.c
pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x"
pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x"
+
+# target-s390/kvm.c
+kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s"
+kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"
diff --git a/ui/gtk.c b/ui/gtk.c
index 00fbbcc..9f5061a 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -93,13 +93,12 @@
#define GDK_KEY_2 GDK_2
#define GDK_KEY_f GDK_f
#define GDK_KEY_g GDK_g
+#define GDK_KEY_q GDK_q
#define GDK_KEY_plus GDK_plus
#define GDK_KEY_minus GDK_minus
#endif
#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK)
-#define IGNORE_MODIFIER_MASK \
- (GDK_MODIFIER_MASK & ~(GDK_LOCK_MASK | GDK_MOD2_MASK))
static const int modifier_keycode[] = {
/* shift, control, alt keys, meta keys, both left & right */
@@ -114,7 +113,6 @@
GtkWidget *scrolled_window;
CharDriverState *chr;
#endif
- int fd;
} VirtualConsole;
typedef struct GtkDisplayState
@@ -489,24 +487,6 @@
/** GTK Events **/
-static gboolean gd_window_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque)
-{
- GtkDisplayState *s = opaque;
- gboolean handled = FALSE;
-
- if (!gd_is_grab_active(s) ||
- (key->state & IGNORE_MODIFIER_MASK) == HOTKEY_MODIFIERS) {
- handled = gtk_window_activate_key(GTK_WINDOW(widget), key);
- }
- if (handled) {
- gtk_release_modifiers(s);
- } else {
- handled = gtk_window_propagate_key_event(GTK_WINDOW(widget), key);
- }
-
- return handled;
-}
-
static gboolean gd_window_close(GtkWidget *widget, GdkEvent *event,
void *opaque)
{
@@ -1161,9 +1141,12 @@
static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
+#if defined(CONFIG_VTE)
VirtualConsole *vc = chr->opaque;
- return vc ? write(vc->fd, buf, len) : len;
+ vte_terminal_feed(VTE_TERMINAL(vc->terminal), (const char *)buf, len);
+#endif
+ return len;
}
static int nb_vcs;
@@ -1189,19 +1172,12 @@
}
#if defined(CONFIG_VTE)
-static gboolean gd_vc_in(GIOChannel *chan, GIOCondition cond, void *opaque)
+static gboolean gd_vc_in(VteTerminal *terminal, gchar *text, guint size,
+ gpointer user_data)
{
- VirtualConsole *vc = opaque;
- uint8_t buffer[1024];
- ssize_t len;
+ VirtualConsole *vc = user_data;
- len = read(vc->fd, buffer, sizeof(buffer));
- if (len <= 0) {
- return FALSE;
- }
-
- qemu_chr_be_write(vc->chr, buffer, len);
-
+ qemu_chr_be_write(vc->chr, (uint8_t *)text, (unsigned int)size);
return TRUE;
}
#endif
@@ -1213,13 +1189,8 @@
const char *label;
char buffer[32];
char path[32];
-#if VTE_CHECK_VERSION(0, 26, 0)
- VtePty *pty;
-#endif
- GIOChannel *chan;
GtkWidget *scrolled_window;
GtkAdjustment *vadjustment;
- int master_fd, slave_fd;
snprintf(buffer, sizeof(buffer), "vc%d", index);
snprintf(path, sizeof(path), "<QEMU>/View/VC%d", index);
@@ -1238,27 +1209,21 @@
gtk_accel_map_add_entry(path, GDK_KEY_2 + index, HOTKEY_MODIFIERS);
vc->terminal = vte_terminal_new();
-
- master_fd = qemu_openpty_raw(&slave_fd, NULL);
- g_assert(master_fd != -1);
-
-#if VTE_CHECK_VERSION(0, 26, 0)
- pty = vte_pty_new_foreign(master_fd, NULL);
- vte_terminal_set_pty_object(VTE_TERMINAL(vc->terminal), pty);
-#else
- vte_terminal_set_pty(VTE_TERMINAL(vc->terminal), master_fd);
-#endif
+ g_signal_connect(vc->terminal, "commit", G_CALLBACK(gd_vc_in), vc);
vte_terminal_set_scrollback_lines(VTE_TERMINAL(vc->terminal), -1);
+#if VTE_CHECK_VERSION(0, 28, 0) && GTK_CHECK_VERSION(3, 0, 0)
+ vadjustment = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vc->terminal));
+#else
vadjustment = vte_terminal_get_adjustment(VTE_TERMINAL(vc->terminal));
+#endif
scrolled_window = gtk_scrolled_window_new(NULL, vadjustment);
gtk_container_add(GTK_CONTAINER(scrolled_window), vc->terminal);
vte_terminal_set_size(VTE_TERMINAL(vc->terminal), 80, 25);
- vc->fd = slave_fd;
vc->chr->opaque = vc;
vc->scrolled_window = scrolled_window;
@@ -1276,9 +1241,6 @@
vc->chr->init(vc->chr);
}
- chan = g_io_channel_unix_new(vc->fd);
- g_io_add_watch(chan, G_IO_IN, gd_vc_in, vc);
-
#endif /* CONFIG_VTE */
return group;
}
@@ -1290,8 +1252,6 @@
g_signal_connect(s->show_tabs_item, "activate",
G_CALLBACK(gd_menu_show_tabs), s);
- g_signal_connect(s->window, "key-press-event",
- G_CALLBACK(gd_window_key_event), s);
g_signal_connect(s->window, "delete-event",
G_CALLBACK(gd_window_close), s);
@@ -1351,7 +1311,6 @@
{
GtkWidget *machine_menu;
GtkWidget *separator;
- GtkStockItem item;
machine_menu = gtk_menu_new();
gtk_menu_set_accel_group(GTK_MENU(machine_menu), accel_group);
@@ -1362,20 +1321,20 @@
separator = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), separator);
- s->reset_item = gtk_image_menu_item_new_with_mnemonic(_("_Reset"));
+ s->reset_item = gtk_menu_item_new_with_mnemonic(_("_Reset"));
gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->reset_item);
- s->powerdown_item = gtk_image_menu_item_new_with_mnemonic(_("Power _Down"));
+ s->powerdown_item = gtk_menu_item_new_with_mnemonic(_("Power _Down"));
gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->powerdown_item);
separator = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), separator);
- s->quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
- gtk_stock_lookup(GTK_STOCK_QUIT, &item);
+ s->quit_item = gtk_menu_item_new_with_mnemonic(_("_Quit"));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->quit_item),
"<QEMU>/Machine/Quit");
- gtk_accel_map_add_entry("<QEMU>/Machine/Quit", item.keyval, item.modifier);
+ gtk_accel_map_add_entry("<QEMU>/Machine/Quit",
+ GDK_KEY_q, HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->quit_item);
return machine_menu;
@@ -1391,8 +1350,7 @@
view_menu = gtk_menu_new();
gtk_menu_set_accel_group(GTK_MENU(view_menu), accel_group);
- s->full_screen_item =
- gtk_image_menu_item_new_from_stock(GTK_STOCK_FULLSCREEN, NULL);
+ s->full_screen_item = gtk_menu_item_new_with_mnemonic(_("_Fullscreen"));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->full_screen_item),
"<QEMU>/View/Full Screen");
gtk_accel_map_add_entry("<QEMU>/View/Full Screen", GDK_KEY_f,
@@ -1402,21 +1360,21 @@
separator = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator);
- s->zoom_in_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_IN, NULL);
+ s->zoom_in_item = gtk_menu_item_new_with_mnemonic(_("Zoom _In"));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_in_item),
"<QEMU>/View/Zoom In");
gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_plus,
HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_in_item);
- s->zoom_out_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_OUT, NULL);
+ s->zoom_out_item = gtk_menu_item_new_with_mnemonic(_("Zoom _Out"));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_out_item),
"<QEMU>/View/Zoom Out");
gtk_accel_map_add_entry("<QEMU>/View/Zoom Out", GDK_KEY_minus,
HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_out_item);
- s->zoom_fixed_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_100, NULL);
+ s->zoom_fixed_item = gtk_menu_item_new_with_mnemonic(_("Best _Fit"));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_fixed_item),
"<QEMU>/View/Zoom Fixed");
gtk_accel_map_add_entry("<QEMU>/View/Zoom Fixed", GDK_KEY_0,
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 7506e2e..361de61 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -359,16 +359,12 @@
}
static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy,
- int dz, int x, int y, int state)
+ int x, int y, int state)
{
static uint32_t bmap[INPUT_BUTTON_MAX] = {
[INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT),
[INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE),
[INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT),
-#if 0
- [INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP),
- [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
-#endif
};
static uint32_t prev_state;
@@ -566,7 +562,7 @@
}
}
if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
- sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel, 0,
+ sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel,
ev->motion.x, ev->motion.y, ev->motion.state);
}
}
@@ -576,7 +572,6 @@
int buttonstate = SDL_GetMouseState(NULL, NULL);
SDL_MouseButtonEvent *bev;
struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);
- int dz;
bev = &ev->button;
if (!gui_grab && !qemu_input_is_absolute()) {
@@ -585,25 +580,35 @@
sdl_grab_start(scon);
}
} else {
- dz = 0;
if (ev->type == SDL_MOUSEBUTTONDOWN) {
buttonstate |= SDL_BUTTON(bev->button);
} else {
buttonstate &= ~SDL_BUTTON(bev->button);
}
-#ifdef SDL_BUTTON_WHEELUP
- if (bev->button == SDL_BUTTON_WHEELUP &&
- ev->type == SDL_MOUSEBUTTONDOWN) {
- dz = -1;
- } else if (bev->button == SDL_BUTTON_WHEELDOWN &&
- ev->type == SDL_MOUSEBUTTONDOWN) {
- dz = 1;
- }
-#endif
- sdl_send_mouse_event(scon, 0, 0, dz, bev->x, bev->y, buttonstate);
+ sdl_send_mouse_event(scon, 0, 0, bev->x, bev->y, buttonstate);
}
}
+static void handle_mousewheel(SDL_Event *ev)
+{
+ struct sdl2_state *scon = get_scon_from_window(ev->key.windowID);
+ SDL_MouseWheelEvent *wev = &ev->wheel;
+ InputButton btn;
+
+ if (wev->y > 0) {
+ btn = INPUT_BUTTON_WHEEL_UP;
+ } else if (wev->y < 0) {
+ btn = INPUT_BUTTON_WHEEL_DOWN;
+ } else {
+ return;
+ }
+
+ qemu_input_queue_btn(scon->dcl.con, btn, true);
+ qemu_input_event_sync();
+ qemu_input_queue_btn(scon->dcl.con, btn, false);
+ qemu_input_event_sync();
+}
+
static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
{
int w, h;
@@ -612,6 +617,13 @@
switch (ev->window.event) {
case SDL_WINDOWEVENT_RESIZED:
sdl_scale(scon, ev->window.data1, ev->window.data2);
+ {
+ QemuUIInfo info;
+ memset(&info, 0, sizeof(info));
+ info.width = ev->window.data1;
+ info.height = ev->window.data2;
+ dpy_set_ui_info(scon->dcl.con, &info);
+ }
graphic_hw_invalidate(scon->dcl.con);
graphic_hw_update(scon->dcl.con);
break;
@@ -678,6 +690,9 @@
case SDL_MOUSEBUTTONUP:
handle_mousebutton(ev);
break;
+ case SDL_MOUSEWHEEL:
+ handle_mousewheel(ev);
+ break;
case SDL_WINDOWEVENT:
handle_windowevent(dcl, ev);
break;
diff --git a/ui/vnc.c b/ui/vnc.c
index 5925774..2d7def9 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -996,7 +996,7 @@
struct audio_capture_ops ops;
if (vs->audio_cap) {
- monitor_printf(default_mon, "audio already running\n");
+ error_report("audio already running");
return;
}
@@ -1006,7 +1006,7 @@
vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
if (!vs->audio_cap) {
- monitor_printf(default_mon, "Failed to add audio capture\n");
+ error_report("Failed to add audio capture");
}
}
diff --git a/util/error.c b/util/error.c
index f11f1d5..2bb42e1 100644
--- a/util/error.c
+++ b/util/error.c
@@ -12,10 +12,7 @@
#include "qemu-common.h"
#include "qapi/error.h"
-#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi-types.h"
-#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
struct Error
{
diff --git a/util/path.c b/util/path.c
index 623219e..5c59d9f 100644
--- a/util/path.c
+++ b/util/path.c
@@ -160,7 +160,9 @@
base = new_entry("", NULL, pref_buf);
base = add_dir_maybe(base);
if (base->num_entries == 0) {
- free (base);
+ g_free(base->pathname);
+ free(base->name);
+ free(base);
base = NULL;
} else {
set_parents(base, base);
diff --git a/util/qemu-config.c b/util/qemu-config.c
index f610101..f4e4f38 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -20,7 +20,7 @@
break;
}
if (lists[i] == NULL) {
- error_set(errp, QERR_INVALID_OPTION_GROUP, group);
+ error_setg(errp, "There is no option group '%s'", group);
}
return lists[i];
}
@@ -39,6 +39,20 @@
return ret;
}
+QemuOpts *qemu_find_opts_singleton(const char *group)
+{
+ QemuOptsList *list;
+ QemuOpts *opts;
+
+ list = qemu_find_opts(group);
+ assert(list);
+ opts = qemu_opts_find(list, NULL);
+ if (!opts) {
+ opts = qemu_opts_create(list, NULL, 0, &error_abort);
+ }
+ return opts;
+}
+
static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
{
CommandLineParameterInfoList *param_list = NULL, *entry;
diff --git a/util/qemu-error.c b/util/qemu-error.c
index fec02c6..7b167fd 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -20,7 +20,7 @@
*/
void error_vprintf(const char *fmt, va_list ap)
{
- if (cur_mon) {
+ if (cur_mon && !monitor_cur_is_qmp()) {
monitor_vprintf(cur_mon, fmt, ap);
} else {
vfprintf(stderr, fmt, ap);
@@ -165,7 +165,7 @@
/*
* Print current location to current monitor if we have one, else to stderr.
*/
-void error_print_loc(void)
+static void error_print_loc(void)
{
const char *sep = "";
int i;
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 9d898af..8bbc3ad 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -819,7 +819,7 @@
opts = qemu_opts_find(list, id);
if (opts != NULL) {
if (fail_if_exists && !list->merge_lists) {
- error_set(errp, QERR_DUPLICATE_ID, id, list->name);
+ error_setg(errp, "Duplicate ID '%s' for %s", id, list->name);
return NULL;
} else {
return opts;
diff --git a/vl.c b/vl.c
index db9ea90..236f95e 100644
--- a/vl.c
+++ b/vl.c
@@ -510,6 +510,20 @@
},
};
+static QemuOptsList qemu_mem_opts = {
+ .name = "memory",
+ .implied_opt_name = "size",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
+ .merge_lists = true,
+ .desc = {
+ {
+ .name = "size",
+ .type = QEMU_OPT_SIZE,
+ },
+ { /* end of list */ }
+ },
+};
+
/**
* Get machine options
*
@@ -517,16 +531,7 @@
*/
QemuOpts *qemu_get_machine_opts(void)
{
- QemuOptsList *list;
- QemuOpts *opts;
-
- list = qemu_find_opts("machine");
- assert(list);
- opts = qemu_opts_find(list, NULL);
- if (!opts) {
- opts = qemu_opts_create(list, NULL, 0, &error_abort);
- }
- return opts;
+ return qemu_find_opts_singleton("machine");
}
const char *qemu_get_vm_name(void)
@@ -2964,6 +2969,8 @@
};
const char *trace_events = NULL;
const char *trace_file = NULL;
+ const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
+ 1024 * 1024;
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
@@ -2987,6 +2994,7 @@
qemu_add_opts(&qemu_trace_opts);
qemu_add_opts(&qemu_option_rom_opts);
qemu_add_opts(&qemu_machine_opts);
+ qemu_add_opts(&qemu_mem_opts);
qemu_add_opts(&qemu_smp_opts);
qemu_add_opts(&qemu_boot_opts);
qemu_add_opts(&qemu_sandbox_opts);
@@ -3011,7 +3019,7 @@
module_call_init(MODULE_INIT_MACHINE);
machine_class = find_default_machine();
cpu_model = NULL;
- ram_size = 0;
+ ram_size = default_ram_size;
snapshot = 0;
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
@@ -3034,7 +3042,6 @@
if (argv[optind][0] != '-') {
/* disk image */
optind++;
- continue;
} else {
const QEMUOption *popt;
@@ -3298,20 +3305,48 @@
exit(0);
break;
case QEMU_OPTION_m: {
- int64_t value;
uint64_t sz;
- char *end;
+ const char *mem_str;
- value = strtosz(optarg, &end);
- if (value < 0 || *end) {
- fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
- exit(1);
+ opts = qemu_opts_parse(qemu_find_opts("memory"),
+ optarg, 1);
+ if (!opts) {
+ exit(EXIT_FAILURE);
}
- sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+
+ mem_str = qemu_opt_get(opts, "size");
+ if (!mem_str) {
+ error_report("invalid -m option, missing 'size' option");
+ exit(EXIT_FAILURE);
+ }
+ if (!*mem_str) {
+ error_report("missing 'size' option value");
+ exit(EXIT_FAILURE);
+ }
+
+ sz = qemu_opt_get_size(opts, "size", ram_size);
+
+ /* Fix up legacy suffix-less format */
+ if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+ uint64_t overflow_check = sz;
+
+ sz <<= 20;
+ if ((sz >> 20) != overflow_check) {
+ error_report("too large 'size' option value");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* backward compatibility behaviour for case "-m 0" */
+ if (sz == 0) {
+ sz = default_ram_size;
+ }
+
+ sz = QEMU_ALIGN_UP(sz, 8192);
ram_size = sz;
if (ram_size != sz) {
- fprintf(stderr, "qemu: ram size too large\n");
- exit(1);
+ error_report("ram size too large");
+ exit(EXIT_FAILURE);
}
break;
}
@@ -3855,7 +3890,9 @@
}
}
qemu_config_write(fp);
- fclose(fp);
+ if (fp != stdout) {
+ fclose(fp);
+ }
break;
}
case QEMU_OPTION_qtest:
@@ -4154,10 +4191,8 @@
exit(1);
}
- /* init the memory */
- if (ram_size == 0) {
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
- }
+ /* store value for the future use */
+ qemu_opt_set_number(qemu_find_opts_singleton("memory"), "size", ram_size);
if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
!= 0) {
@@ -4371,15 +4406,15 @@
qdev_machine_init();
- QEMUMachineInitArgs args = { .machine = machine,
- .ram_size = ram_size,
- .boot_order = boot_order,
- .kernel_filename = kernel_filename,
- .kernel_cmdline = kernel_cmdline,
- .initrd_filename = initrd_filename,
- .cpu_model = cpu_model };
+ current_machine->init_args = (QEMUMachineInitArgs) {
+ .machine = machine,
+ .ram_size = ram_size,
+ .boot_order = boot_order,
+ .kernel_filename = kernel_filename,
+ .kernel_cmdline = kernel_cmdline,
+ .initrd_filename = initrd_filename,
+ .cpu_model = cpu_model };
- current_machine->init_args = args;
machine->init(¤t_machine->init_args);
audio_init();