aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HACKING7
-rwxr-xr-xQMP/qmp-shell2
-rw-r--r--VERSION2
-rw-r--r--block.c8
-rw-r--r--block/nbd.c2
-rw-r--r--block/qcow2-cluster.c23
-rw-r--r--block/qcow2.c13
-rw-r--r--block/qcow2.h5
-rw-r--r--bsd-user/syscall.c7
-rwxr-xr-xconfigure16
-rw-r--r--docs/memory.txt11
-rw-r--r--exec.c14
-rw-r--r--fsdev/virtfs-proxy-helper.c4
-rw-r--r--hw/9pfs/virtio-9p-local.c2
-rw-r--r--hw/acpi/core.c7
-rw-r--r--hw/arm/spitz.c100
-rw-r--r--hw/block/m25p80.c31
-rw-r--r--hw/block/pc_sysfw.c8
-rw-r--r--hw/display/qxl.c3
-rw-r--r--hw/i386/pc_piix.c3
-rw-r--r--hw/i386/pc_q35.c3
-rw-r--r--hw/intc/imx_avic.c2
-rw-r--r--hw/net/virtio-net.c45
-rw-r--r--hw/pci-host/versatile.c85
-rw-r--r--hw/s390x/s390-virtio-bus.c3
-rw-r--r--hw/s390x/virtio-ccw.c3
-rw-r--r--hw/usb/host-linux.c4
-rw-r--r--hw/virtio/virtio-bus.c14
-rw-r--r--hw/virtio/virtio-pci.c3
-rw-r--r--include/hw/i386/pc.h5
-rw-r--r--include/hw/virtio/virtio-net.h4
-rw-r--r--include/qemu-common.h22
-rw-r--r--include/qemu/osdep.h5
-rw-r--r--include/qom/object.h44
-rw-r--r--include/sysemu/kvm.h4
-rw-r--r--kvm-all.c6
-rw-r--r--main-loop.c40
-rw-r--r--migration.c5
-rw-r--r--qemu-char.c10
-rw-r--r--qemu-doc.texi4
-rw-r--r--qga/channel-win32.c2
-rw-r--r--qom/object.c87
-rw-r--r--readline.c15
-rw-r--r--target-s390x/kvm.c2
-rw-r--r--tests/ide-test.c32
-rw-r--r--tests/test-visitor-serialization.c9
-rw-r--r--trace-events6
-rw-r--r--ui/gtk.c20
-rw-r--r--ui/vnc.c3
-rw-r--r--util/oslib-posix.c12
-rw-r--r--util/oslib-win32.c12
-rw-r--r--util/uri.c2
-rw-r--r--vl.c2
53 files changed, 574 insertions, 209 deletions
diff --git a/HACKING b/HACKING
index 6654d33249..e73ac79fe9 100644
--- a/HACKING
+++ b/HACKING
@@ -78,16 +78,15 @@ avoided.
Use of the malloc/free/realloc/calloc/valloc/memalign/posix_memalign
APIs is not allowed in the QEMU codebase. Instead of these routines,
use the GLib memory allocation routines g_malloc/g_malloc0/g_new/
-g_new0/g_realloc/g_free or QEMU's qemu_vmalloc/qemu_memalign/qemu_vfree
+g_new0/g_realloc/g_free or QEMU's qemu_memalign/qemu_blockalign/qemu_vfree
APIs.
Please note that g_malloc will exit on allocation failure, so there
is no need to test for failure (as you would have to with malloc).
Calling g_malloc with a zero size is valid and will return NULL.
-Memory allocated by qemu_vmalloc or qemu_memalign must be freed with
-qemu_vfree, since breaking this will cause problems on Win32 and user
-emulators.
+Memory allocated by qemu_memalign or qemu_blockalign must be freed with
+qemu_vfree, since breaking this will cause problems on Win32.
4. String manipulation
diff --git a/QMP/qmp-shell b/QMP/qmp-shell
index d126e63ad1..73cb3b6cef 100755
--- a/QMP/qmp-shell
+++ b/QMP/qmp-shell
@@ -99,6 +99,8 @@ class QMPShell(qmp.QEMUMonitorProtocol):
for arg in cmdargs[1:]:
opt = arg.split('=')
try:
+ if(len(opt) > 2):
+ opt[1] = '='.join(opt[1:])
value = int(opt[1])
except ValueError:
if opt[1] == 'true':
diff --git a/VERSION b/VERSION
index 8d9b8b2df9..0101924abf 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.4.91
+1.4.92
diff --git a/block.c b/block.c
index aa9a533355..3f87489937 100644
--- a/block.c
+++ b/block.c
@@ -4857,8 +4857,12 @@ void bdrv_img_create(const char *filename, const char *fmt,
error_setg(errp,"Formatting or formatting option not supported for "
"file format '%s'", fmt);
} else if (ret == -EFBIG) {
- error_setg(errp, "The image size is too large for file format '%s'",
- fmt);
+ const char *cluster_size_hint = "";
+ if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
+ cluster_size_hint = " (try using a larger cluster size)";
+ }
+ error_setg(errp, "The image size is too large for file format '%s'%s",
+ fmt, cluster_size_hint);
} else {
error_setg(errp, "%s: error while creating %s: %s", filename, fmt,
strerror(-ret));
diff --git a/block/nbd.c b/block/nbd.c
index fab114bbb5..30e3b78e17 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -609,7 +609,7 @@ static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num,
return 0;
}
request.type = NBD_CMD_TRIM;
- request.from = sector_num * 512;;
+ request.from = sector_num * 512;
request.len = nb_sectors * 512;
nbd_coroutine_start(s, &request);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index c71470a3db..76f30e5c26 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -29,12 +29,13 @@
#include "block/qcow2.h"
#include "trace.h"
-int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
+int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
+ bool exact_size)
{
BDRVQcowState *s = bs->opaque;
- int new_l1_size, new_l1_size2, ret, i;
+ int new_l1_size2, ret, i;
uint64_t *new_l1_table;
- int64_t new_l1_table_offset;
+ int64_t new_l1_table_offset, new_l1_size;
uint8_t data[12];
if (min_size <= s->l1_size)
@@ -53,8 +54,13 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
}
}
+ if (new_l1_size > INT_MAX) {
+ return -EFBIG;
+ }
+
#ifdef DEBUG_ALLOC2
- fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
+ fprintf(stderr, "grow l1_table from %d to %" PRId64 "\n",
+ s->l1_size, new_l1_size);
#endif
new_l1_size2 = sizeof(uint64_t) * new_l1_size;
@@ -391,8 +397,8 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
int *num, uint64_t *cluster_offset)
{
BDRVQcowState *s = bs->opaque;
- unsigned int l1_index, l2_index;
- uint64_t l2_offset, *l2_table;
+ unsigned int l2_index;
+ uint64_t l1_index, l2_offset, *l2_table;
int l1_bits, c;
unsigned int index_in_cluster, nb_clusters;
uint64_t nb_available, nb_needed;
@@ -507,8 +513,8 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
int *new_l2_index)
{
BDRVQcowState *s = bs->opaque;
- unsigned int l1_index, l2_index;
- uint64_t l2_offset;
+ unsigned int l2_index;
+ uint64_t l1_index, l2_offset;
uint64_t *l2_table = NULL;
int ret;
@@ -522,6 +528,7 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
}
}
+ assert(l1_index < s->l1_size);
l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;
/* seek the l2 table of the given l2 offset */
diff --git a/block/qcow2.c b/block/qcow2.c
index 2e346d8c42..0fa5cb29ae 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -307,6 +307,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
QemuOpts *opts;
Error *local_err = NULL;
uint64_t ext_end;
+ uint64_t l1_vm_state_index;
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
if (ret < 0) {
@@ -424,7 +425,14 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
/* read the level 1 table */
s->l1_size = header.l1_size;
- s->l1_vm_state_index = size_to_l1(s, header.size);
+
+ l1_vm_state_index = size_to_l1(s, header.size);
+ if (l1_vm_state_index > INT_MAX) {
+ ret = -EFBIG;
+ goto fail;
+ }
+ s->l1_vm_state_index = l1_vm_state_index;
+
/* the L1 table must contain at least enough entries to put
header.size bytes */
if (s->l1_size < s->l1_vm_state_index) {
@@ -1480,7 +1488,8 @@ static coroutine_fn int qcow2_co_discard(BlockDriverState *bs,
static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
{
BDRVQcowState *s = bs->opaque;
- int ret, new_l1_size;
+ int64_t new_l1_size;
+ int ret;
if (offset & 511) {
error_report("The new size must be a multiple of 512");
diff --git a/block/qcow2.h b/block/qcow2.h
index 94218432f3..6959c6a05f 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -284,7 +284,7 @@ static inline int size_to_clusters(BDRVQcowState *s, int64_t size)
return (size + (s->cluster_size - 1)) >> s->cluster_bits;
}
-static inline int size_to_l1(BDRVQcowState *s, int64_t size)
+static inline int64_t size_to_l1(BDRVQcowState *s, int64_t size)
{
int shift = s->cluster_bits + s->l2_bits;
return (size + (1ULL << shift) - 1) >> shift;
@@ -360,7 +360,8 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
BdrvCheckMode fix);
/* qcow2-cluster.c functions */
-int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size);
+int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
+ bool exact_size);
void qcow2_l2_cache_reset(BlockDriverState *bs);
int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 69e3466a08..a4d1583fed 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -211,10 +211,11 @@ static int sysctl_oldcvt(void *holdp, size_t holdlen, uint32_t kind)
*(uint64_t *)holdp = tswap64(*(unsigned long *)holdp);
break;
#endif
-#if !defined(__FreeBSD_version) || __FreeBSD_version < 900031
- case CTLTYPE_QUAD:
-#else
+#ifdef CTLTYPE_U64
+ case CTLTYPE_S64:
case CTLTYPE_U64:
+#else
+ case CTLTYPE_QUAD:
#endif
*(uint64_t *)holdp = tswap64(*(uint64_t *)holdp);
break;
diff --git a/configure b/configure
index 9439f1c727..5ae7e4a348 100755
--- a/configure
+++ b/configure
@@ -220,6 +220,7 @@ blobs="yes"
pkgversion=""
pie=""
zero_malloc=""
+qom_cast_debug="yes"
trace_backend="nop"
trace_file="trace"
spice=""
@@ -688,6 +689,10 @@ for opt do
;;
--enable-sdl) sdl="yes"
;;
+ --disable-qom-cast-debug) qom_cast_debug="no"
+ ;;
+ --enable-qom-cast-debug) qom_cast_debug="yes"
+ ;;
--disable-virtfs) virtfs="no"
;;
--enable-virtfs) virtfs="yes"
@@ -1341,6 +1346,7 @@ static int sfaa(int *ptr)
int main(void)
{
int val = 42;
+ val = __sync_val_compare_and_swap(&val, 0, 1);
sfaa(&val);
return val;
}
@@ -1943,6 +1949,8 @@ fi
##########################################
# uuid_generate() probe, used for vdi block driver
+# Note that on some systems (notably MacOSX) no extra library
+# need be linked to get the uuid functions.
if test "$uuid" != "no" ; then
uuid_libs="-luuid"
cat > $TMPC << EOF
@@ -1954,7 +1962,9 @@ int main(void)
return 0;
}
EOF
- if compile_prog "" "$uuid_libs" ; then
+ if compile_prog "" "" ; then
+ uuid="yes"
+ elif compile_prog "" "$uuid_libs" ; then
uuid="yes"
libs_softmmu="$uuid_libs $libs_softmmu"
libs_tools="$uuid_libs $libs_tools"
@@ -3575,6 +3585,7 @@ echo "gcov enabled $gcov"
echo "TPM support $tpm"
echo "libssh2 support $libssh2"
echo "TPM passthrough $tpm_passthrough"
+echo "QOM debugging $qom_cast_debug"
if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -3909,6 +3920,9 @@ echo "CONFIG_UNAME_RELEASE=\"$uname_release\"" >> $config_host_mak
if test "$zero_malloc" = "yes" ; then
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
fi
+if test "$qom_cast_debug" = "yes" ; then
+ echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
+fi
if test "$rbd" = "yes" ; then
echo "CONFIG_RBD=y" >> $config_host_mak
fi
diff --git a/docs/memory.txt b/docs/memory.txt
index 5bbee8e85d..feb9fe90d7 100644
--- a/docs/memory.txt
+++ b/docs/memory.txt
@@ -15,10 +15,13 @@ The memory model provides support for
- setting up coalesced memory for kvm
- setting up ioeventfd regions for kvm
-Memory is modelled as a tree (really acyclic graph) of MemoryRegion objects.
-The root of the tree is memory as seen from the CPU's viewpoint (the system
-bus). Nodes in the tree represent other buses, memory controllers, and
-memory regions that have been rerouted. Leaves are RAM and MMIO regions.
+Memory is modelled as an acyclic graph of MemoryRegion objects. Sinks
+(leaves) are RAM and MMIO regions, while other nodes represent
+buses, memory controllers, and memory regions that have been rerouted.
+
+In addition to MemoryRegion objects, the memory API provides AddressSpace
+objects for every root and possibly for intermediate MemoryRegions too.
+These represent memory as seen from the CPU or a device's viewpoint.
Types of regions
----------------
diff --git a/exec.c b/exec.c
index 19725dbc05..aec65c5063 100644
--- a/exec.c
+++ b/exec.c
@@ -1062,7 +1062,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
#if defined (__linux__) && !defined(TARGET_S390X)
new_block->host = file_ram_alloc(new_block, size, mem_path);
if (!new_block->host) {
- new_block->host = qemu_vmalloc(size);
+ new_block->host = qemu_anon_ram_alloc(size);
memory_try_enable_merging(new_block->host, size);
}
#else
@@ -1074,9 +1074,9 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
xen_ram_alloc(new_block->offset, size, mr);
} else if (kvm_enabled()) {
/* some s390/kvm configurations have special constraints */
- new_block->host = kvm_vmalloc(size);
+ new_block->host = kvm_ram_alloc(size);
} else {
- new_block->host = qemu_vmalloc(size);
+ new_block->host = qemu_anon_ram_alloc(size);
}
memory_try_enable_merging(new_block->host, size);
}
@@ -1156,21 +1156,17 @@ void qemu_ram_free(ram_addr_t addr)
munmap(block->host, block->length);
close(block->fd);
} else {
- qemu_vfree(block->host);
+ qemu_anon_ram_free(block->host, block->length);
}
#else
abort();
#endif
} else {
-#if defined(TARGET_S390X) && defined(CONFIG_KVM)
- munmap(block->host, block->length);
-#else
if (xen_enabled()) {
xen_invalidate_map_cache_entry(block->host);
} else {
- qemu_vfree(block->host);
+ qemu_anon_ram_free(block->host, block->length);
}
-#endif
}
g_free(block);
break;
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index 36f66163b2..713a7b2b87 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -248,7 +248,7 @@ static int send_fd(int sockfd, int fd)
static int send_status(int sockfd, struct iovec *iovec, int status)
{
ProxyHeader header;
- int retval, msg_size;;
+ int retval, msg_size;
if (status < 0) {
header.type = T_ERROR;
@@ -381,7 +381,7 @@ static int send_response(int sock, struct iovec *iovec, int size)
proxy_marshal(iovec, 0, "dd", header.type, header.size);
retval = socket_write(sock, iovec->iov_base, header.size + PROXY_HDR_SZ);
if (retval < 0) {
- return retval;;
+ return retval;
}
return 0;
}
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index be898eccd9..6ece6f7d1c 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -878,7 +878,7 @@ static int local_remove(FsContext *ctx, const char *path)
* Now remove the name from parent directory
* .virtfs_metadata directory
*/
- err = remove(local_mapped_attr_path(ctx, path, buffer));;
+ err = remove(local_mapped_attr_path(ctx, path, buffer));
if (err < 0 && errno != ENOENT) {
/*
* We didn't had the .virtfs_metadata file. May be file created
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 64b871846d..42eeace6f6 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -462,8 +462,15 @@ static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width)
return acpi_pm_tmr_get(opaque);
}
+static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned width)
+{
+ /* nothing */
+}
+
static const MemoryRegionOps acpi_pm_tmr_ops = {
.read = acpi_pm_tmr_read,
+ .write = acpi_pm_tmr_write,
.valid.min_access_size = 4,
.valid.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index c42668ae49..b5ed109479 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -277,9 +277,9 @@ static void spitz_keyboard_keydown(SpitzKeyboardState *s, int keycode)
spitz_keyboard_sense_update(s);
}
-#define SHIFT (1 << 7)
-#define CTRL (1 << 8)
-#define FN (1 << 9)
+#define MOD_SHIFT (1 << 7)
+#define MOD_CTRL (1 << 8)
+#define MOD_FN (1 << 9)
#define QUEUE_KEY(c) s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
@@ -316,20 +316,20 @@ static void spitz_keyboard_handler(void *opaque, int keycode)
}
code = s->pre_map[mapcode = ((s->modifiers & 3) ?
- (keycode | SHIFT) :
- (keycode & ~SHIFT))];
+ (keycode | MOD_SHIFT) :
+ (keycode & ~MOD_SHIFT))];
if (code != mapcode) {
#if 0
- if ((code & SHIFT) && !(s->modifiers & 1))
+ if ((code & MOD_SHIFT) && !(s->modifiers & 1))
QUEUE_KEY(0x2a | (keycode & 0x80));
- if ((code & CTRL ) && !(s->modifiers & 4))
+ if ((code & MOD_CTRL ) && !(s->modifiers & 4))
QUEUE_KEY(0x1d | (keycode & 0x80));
- if ((code & FN ) && !(s->modifiers & 8))
+ if ((code & MOD_FN ) && !(s->modifiers & 8))
QUEUE_KEY(0x38 | (keycode & 0x80));
- if ((code & FN ) && (s->modifiers & 1))
+ if ((code & MOD_FN ) && (s->modifiers & 1))
QUEUE_KEY(0x2a | (~keycode & 0x80));
- if ((code & FN ) && (s->modifiers & 2))
+ if ((code & MOD_FN ) && (s->modifiers & 2))
QUEUE_KEY(0x36 | (~keycode & 0x80));
#else
if (keycode & 0x80) {
@@ -345,24 +345,24 @@ static void spitz_keyboard_handler(void *opaque, int keycode)
QUEUE_KEY(0x36);
s->imodifiers = 0;
} else {
- if ((code & SHIFT) && !((s->modifiers | s->imodifiers) & 1)) {
+ if ((code & MOD_SHIFT) && !((s->modifiers | s->imodifiers) & 1)) {
QUEUE_KEY(0x2a);
s->imodifiers |= 1;
}
- if ((code & CTRL ) && !((s->modifiers | s->imodifiers) & 4)) {
+ if ((code & MOD_CTRL ) && !((s->modifiers | s->imodifiers) & 4)) {
QUEUE_KEY(0x1d);
s->imodifiers |= 4;
}
- if ((code & FN ) && !((s->modifiers | s->imodifiers) & 8)) {
+ if ((code & MOD_FN ) && !((s->modifiers | s->imodifiers) & 8)) {
QUEUE_KEY(0x38);
s->imodifiers |= 8;
}
- if ((code & FN ) && (s->modifiers & 1) &&
+ if ((code & MOD_FN ) && (s->modifiers & 1) &&
!(s->imodifiers & 0x10)) {
QUEUE_KEY(0x2a | 0x80);
s->imodifiers |= 0x10;
}
- if ((code & FN ) && (s->modifiers & 2) &&
+ if ((code & MOD_FN ) && (s->modifiers & 2) &&
!(s->imodifiers & 0x20)) {
QUEUE_KEY(0x36 | 0x80);
s->imodifiers |= 0x20;
@@ -394,38 +394,38 @@ static void spitz_keyboard_pre_map(SpitzKeyboardState *s)
int i;
for (i = 0; i < 0x100; i ++)
s->pre_map[i] = i;
- s->pre_map[0x02 | SHIFT ] = 0x02 | SHIFT; /* exclam */
- s->pre_map[0x28 | SHIFT ] = 0x03 | SHIFT; /* quotedbl */
- s->pre_map[0x04 | SHIFT ] = 0x04 | SHIFT; /* numbersign */
- s->pre_map[0x05 | SHIFT ] = 0x05 | SHIFT; /* dollar */
- s->pre_map[0x06 | SHIFT ] = 0x06 | SHIFT; /* percent */
- s->pre_map[0x08 | SHIFT ] = 0x07 | SHIFT; /* ampersand */
- s->pre_map[0x28 ] = 0x08 | SHIFT; /* apostrophe */
- s->pre_map[0x0a | SHIFT ] = 0x09 | SHIFT; /* parenleft */
- s->pre_map[0x0b | SHIFT ] = 0x0a | SHIFT; /* parenright */
- s->pre_map[0x29 | SHIFT ] = 0x0b | SHIFT; /* asciitilde */
- s->pre_map[0x03 | SHIFT ] = 0x0c | SHIFT; /* at */
- s->pre_map[0xd3 ] = 0x0e | FN; /* Delete */
- s->pre_map[0x3a ] = 0x0f | FN; /* Caps_Lock */
- s->pre_map[0x07 | SHIFT ] = 0x11 | FN; /* asciicircum */
- s->pre_map[0x0d ] = 0x12 | FN; /* equal */
- s->pre_map[0x0d | SHIFT ] = 0x13 | FN; /* plus */
- s->pre_map[0x1a ] = 0x14 | FN; /* bracketleft */
- s->pre_map[0x1b ] = 0x15 | FN; /* bracketright */
- s->pre_map[0x1a | SHIFT ] = 0x16 | FN; /* braceleft */
- s->pre_map[0x1b | SHIFT ] = 0x17 | FN; /* braceright */
- s->pre_map[0x27 ] = 0x22 | FN; /* semicolon */
- s->pre_map[0x27 | SHIFT ] = 0x23 | FN; /* colon */
- s->pre_map[0x09 | SHIFT ] = 0x24 | FN; /* asterisk */
- s->pre_map[0x2b ] = 0x25 | FN; /* backslash */
- s->pre_map[0x2b | SHIFT ] = 0x26 | FN; /* bar */
- s->pre_map[0x0c | SHIFT ] = 0x30 | FN; /* underscore */
- s->pre_map[0x33 | SHIFT ] = 0x33 | FN; /* less */
- s->pre_map[0x35 ] = 0x33 | SHIFT; /* slash */
- s->pre_map[0x34 | SHIFT ] = 0x34 | FN; /* greater */
- s->pre_map[0x35 | SHIFT ] = 0x34 | SHIFT; /* question */
- s->pre_map[0x49 ] = 0x48 | FN; /* Page_Up */
- s->pre_map[0x51 ] = 0x50 | FN; /* Page_Down */
+ s->pre_map[0x02 | MOD_SHIFT ] = 0x02 | MOD_SHIFT; /* exclam */
+ s->pre_map[0x28 | MOD_SHIFT ] = 0x03 | MOD_SHIFT; /* quotedbl */
+ s->pre_map[0x04 | MOD_SHIFT ] = 0x04 | MOD_SHIFT; /* numbersign */
+ s->pre_map[0x05 | MOD_SHIFT ] = 0x05 | MOD_SHIFT; /* dollar */
+ s->pre_map[0x06 | MOD_SHIFT ] = 0x06 | MOD_SHIFT; /* percent */
+ s->pre_map[0x08 | MOD_SHIFT ] = 0x07 | MOD_SHIFT; /* ampersand */
+ s->pre_map[0x28 ] = 0x08 | MOD_SHIFT; /* apostrophe */
+ s->pre_map[0x0a | MOD_SHIFT ] = 0x09 | MOD_SHIFT; /* parenleft */
+ s->pre_map[0x0b | MOD_SHIFT ] = 0x0a | MOD_SHIFT; /* parenright */
+ s->pre_map[0x29 | MOD_SHIFT ] = 0x0b | MOD_SHIFT; /* asciitilde */
+ s->pre_map[0x03 | MOD_SHIFT ] = 0x0c | MOD_SHIFT; /* at */
+ s->pre_map[0xd3 ] = 0x0e | MOD_FN; /* Delete */
+ s->pre_map[0x3a ] = 0x0f | MOD_FN; /* Caps_Lock */
+ s->pre_map[0x07 | MOD_SHIFT ] = 0x11 | MOD_FN; /* asciicircum */
+ s->pre_map[0x0d ] = 0x12 | MOD_FN; /* equal */
+ s->pre_map[0x0d | MOD_SHIFT ] = 0x13 | MOD_FN; /* plus */
+ s->pre_map[0x1a ] = 0x14 | MOD_FN; /* bracketleft */
+ s->pre_map[0x1b ] = 0x15 | MOD_FN; /* bracketright */
+ s->pre_map[0x1a | MOD_SHIFT ] = 0x16 | MOD_FN; /* braceleft */
+ s->pre_map[0x1b | MOD_SHIFT ] = 0x17 | MOD_FN; /* braceright */
+ s->pre_map[0x27 ] = 0x22 | MOD_FN; /* semicolon */
+ s->pre_map[0x27 | MOD_SHIFT ] = 0x23 | MOD_FN; /* colon */
+ s->pre_map[0x09 | MOD_SHIFT ] = 0x24 | MOD_FN; /* asterisk */
+ s->pre_map[0x2b ] = 0x25 | MOD_FN; /* backslash */
+ s->pre_map[0x2b | MOD_SHIFT ] = 0x26 | MOD_FN; /* bar */
+ s->pre_map[0x0c | MOD_SHIFT ] = 0x30 | MOD_FN; /* underscore */
+ s->pre_map[0x33 | MOD_SHIFT ] = 0x33 | MOD_FN; /* less */
+ s->pre_map[0x35 ] = 0x33 | MOD_SHIFT; /* slash */
+ s->pre_map[0x34 | MOD_SHIFT ] = 0x34 | MOD_FN; /* greater */
+ s->pre_map[0x35 | MOD_SHIFT ] = 0x34 | MOD_SHIFT; /* question */
+ s->pre_map[0x49 ] = 0x48 | MOD_FN; /* Page_Up */
+ s->pre_map[0x51 ] = 0x50 | MOD_FN; /* Page_Down */
s->modifiers = 0;
s->imodifiers = 0;
@@ -433,9 +433,9 @@ static void spitz_keyboard_pre_map(SpitzKeyboardState *s)
s->fifolen = 0;
}
-#undef SHIFT
-#undef CTRL
-#undef FN
+#undef MOD_SHIFT
+#undef MOD_CTRL
+#undef MOD_FN
static int spitz_keyboard_post_load(void *opaque, int version_id)
{
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index b3ca19ae52..759c84d140 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -91,18 +91,27 @@ static const FlashPartInfo known_devices[] = {
{ INFO("at26df161a", 0x1f4601, 0, 64 << 10, 32, ER_4K) },
{ INFO("at26df321", 0x1f4700, 0, 64 << 10, 64, ER_4K) },
+ { INFO("at45db081d", 0x1f2500, 0, 64 << 10, 16, ER_4K) },
+
/* EON -- en25xxx */
{ INFO("en25f32", 0x1c3116, 0, 64 << 10, 64, ER_4K) },
{ INFO("en25p32", 0x1c2016, 0, 64 << 10, 64, 0) },
{ INFO("en25q32b", 0x1c3016, 0, 64 << 10, 64, 0) },
{ INFO("en25p64", 0x1c2017, 0, 64 << 10, 128, 0) },
+ { INFO("en25q64", 0x1c3017, 0, 64 << 10, 128, ER_4K) },
+
+ /* GigaDevice */
+ { INFO("gd25q32", 0xc84016, 0, 64 << 10, 64, ER_4K) },
+ { INFO("gd25q64", 0xc84017, 0, 64 << 10, 128, ER_4K) },
/* Intel/Numonyx -- xxxs33b */
{ INFO("160s33b", 0x898911, 0, 64 << 10, 32, 0) },
{ INFO("320s33b", 0x898912, 0, 64 << 10, 64, 0) },
{ INFO("640s33b", 0x898913, 0, 64 << 10, 128, 0) },
+ { INFO("n25q064", 0x20ba17, 0, 64 << 10, 128, 0) },
/* Macronix */
+ { INFO("mx25l2005a", 0xc22012, 0, 64 << 10, 4, ER_4K) },
{ INFO("mx25l4005a", 0xc22013, 0, 64 << 10, 8, ER_4K) },
{ INFO("mx25l8005", 0xc22014, 0, 64 << 10, 16, 0) },
{ INFO("mx25l1606e", 0xc22015, 0, 64 << 10, 32, ER_4K) },
@@ -113,15 +122,16 @@ static const FlashPartInfo known_devices[] = {
{ INFO("mx25l25635e", 0xc22019, 0, 64 << 10, 512, 0) },
{ INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) },
+ /* Micron */
+ { INFO("n25q128a11", 0x20bb18, 0, 64 << 10, 256, 0) },
+ { INFO("n25q128a13", 0x20ba18, 0, 64 << 10, 256, 0) },
+ { INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
+
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/
- { INFO("s25sl004a", 0x010212, 0, 64 << 10, 8, 0) },
- { INFO("s25sl008a", 0x010213, 0, 64 << 10, 16, 0) },
- { INFO("s25sl016a", 0x010214, 0, 64 << 10, 32, 0) },
- { INFO("s25sl032a", 0x010215, 0, 64 << 10, 64, 0) },
{ INFO("s25sl032p", 0x010215, 0x4d00, 64 << 10, 64, ER_4K) },
- { INFO("s25sl064a", 0x010216, 0, 64 << 10, 128, 0) },
+ { INFO("s25sl064p", 0x010216, 0x4d00, 64 << 10, 128, ER_4K) },
{ INFO("s25fl256s0", 0x010219, 0x4d00, 256 << 10, 128, 0) },
{ INFO("s25fl256s1", 0x010219, 0x4d01, 64 << 10, 512, 0) },
{ INFO("s25fl512s", 0x010220, 0x4d00, 256 << 10, 256, 0) },
@@ -130,6 +140,11 @@ static const FlashPartInfo known_devices[] = {
{ INFO("s25sl12801", 0x012018, 0x0301, 64 << 10, 256, 0) },
{ INFO("s25fl129p0", 0x012018, 0x4d00, 256 << 10, 64, 0) },
{ INFO("s25fl129p1", 0x012018, 0x4d01, 64 << 10, 256, 0) },
+ { INFO("s25sl004a", 0x010212, 0, 64 << 10, 8, 0) },
+ { INFO("s25sl008a", 0x010213, 0, 64 << 10, 16, 0) },
+ { INFO("s25sl016a", 0x010214, 0, 64 << 10, 32, 0) },
+ { INFO("s25sl032a", 0x010215, 0, 64 << 10, 64, 0) },
+ { INFO("s25sl064a", 0x010216, 0, 64 << 10, 128, 0) },
{ INFO("s25fl016k", 0xef4015, 0, 64 << 10, 32, ER_4K | ER_32K) },
{ INFO("s25fl064k", 0xef4017, 0, 64 << 10, 128, ER_4K | ER_32K) },
@@ -153,11 +168,13 @@ static const FlashPartInfo known_devices[] = {
{ INFO("m25p32", 0x202016, 0, 64 << 10, 64, 0) },
{ INFO("m25p64", 0x202017, 0, 64 << 10, 128, 0) },
{ INFO("m25p128", 0x202018, 0, 256 << 10, 64, 0) },
+ { INFO("n25q032", 0x20ba16, 0, 64 << 10, 64, 0) },
{ INFO("m45pe10", 0x204011, 0, 64 << 10, 2, 0) },
{ INFO("m45pe80", 0x204014, 0, 64 << 10, 16, 0) },
{ INFO("m45pe16", 0x204015, 0, 64 << 10, 32, 0) },
+ { INFO("m25pe20", 0x208012, 0, 64 << 10, 4, 0) },
{ INFO("m25pe80", 0x208014, 0, 64 << 10, 16, 0) },
{ INFO("m25pe16", 0x208015, 0, 64 << 10, 32, ER_4K) },
@@ -174,8 +191,12 @@ static const FlashPartInfo known_devices[] = {
{ INFO("w25x16", 0xef3015, 0, 64 << 10, 32, ER_4K) },
{ INFO("w25x32", 0xef3016, 0, 64 << 10, 64, ER_4K) },
{ INFO("w25q32", 0xef4016, 0, 64 << 10, 64, ER_4K) },
+ { INFO("w25q32dw", 0xef6016, 0, 64 << 10, 64, ER_4K) },
{ INFO("w25x64", 0xef3017, 0, 64 << 10, 128, ER_4K) },
{ INFO("w25q64", 0xef4017, 0, 64 << 10, 128, ER_4K) },
+ { INFO("w25q80", 0xef5014, 0, 64 << 10, 16, ER_4K) },
+ { INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) },
+ { INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K) },
/* Numonyx -- n25q128 */
{ INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) },
diff --git a/hw/block/pc_sysfw.c b/hw/block/pc_sysfw.c
index aad8614465..4f17668503 100644
--- a/hw/block/pc_sysfw.c
+++ b/hw/block/pc_sysfw.c
@@ -209,7 +209,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
* TODO This device exists only so that users can switch between
* use of flash and ROM for the BIOS. The ability to switch was
* created because flash doesn't work with KVM. Once it does, we
- * should drop this device for new machine types.
+ * should drop this device.
*/
sysfw_dev = (PcSysFwDevice*) qdev_create(NULL, "pc-sysfw");
@@ -226,9 +226,9 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
Use old rom based firmware initialization for KVM. */
/*
* This is a Bad Idea, because it makes enabling/disabling KVM
- * guest-visible. Do it only in bug-compatibility mode.
+ * guest-visible. Let's fix it for real in QEMU 1.6.
*/
- if (pc_sysfw_flash_vs_rom_bug_compatible && kvm_enabled()) {
+ if (kvm_enabled()) {
if (pflash_drv != NULL) {
fprintf(stderr, "qemu: pflash cannot be used with kvm enabled\n");
exit(1);
@@ -255,7 +255,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
}
static Property pcsysfw_properties[] = {
- DEFINE_PROP_UINT8("rom_only", PcSysFwDevice, rom_only, 1),
+ DEFINE_PROP_UINT8("rom_only", PcSysFwDevice, rom_only, 0),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 2d49e9a720..c475cb10dc 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1077,6 +1077,9 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
return;
}
trace_qxl_enter_vga_mode(d->id);
+#if SPICE_SERVER_VERSION >= 0x000c03 /* release 0.12.3 */
+ spice_qxl_driver_unload(&d->ssd.qxl);
+#endif
qemu_spice_create_host_primary(&d->ssd);
d->mode = QXL_MODE_VGA;
vga_dirty_log_start(&d->vga);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index f7c80ad0a5..43ab4807ae 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -248,7 +248,6 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
{
- pc_sysfw_flash_vs_rom_bug_compatible = true;
has_pvpanic = false;
x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
pc_init_pci(args);
@@ -257,7 +256,6 @@ static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
{
enable_compat_apic_id_mode();
- pc_sysfw_flash_vs_rom_bug_compatible = true;
has_pvpanic = false;
pc_init_pci(args);
}
@@ -267,7 +265,6 @@ static void pc_init_pci_1_2(QEMUMachineInitArgs *args)
{
disable_kvm_pv_eoi();
enable_compat_apic_id_mode();
- pc_sysfw_flash_vs_rom_bug_compatible = true;
has_pvpanic = false;
pc_init_pci(args);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 4160e2ba37..7888dfe03f 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -128,7 +128,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
q35_host->mch.ram_memory = ram_memory;
q35_host->mch.pci_address_space = pci_memory;
q35_host->mch.system_memory = get_system_memory();
- q35_host->mch.address_space_io = get_system_io();;
+ q35_host->mch.address_space_io = get_system_io();
q35_host->mch.below_4g_mem_size = below_4g_mem_size;
q35_host->mch.above_4g_mem_size = above_4g_mem_size;
/* pci */
@@ -210,7 +210,6 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
{
- pc_sysfw_flash_vs_rom_bug_compatible = true;
has_pvpanic = false;
x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
pc_q35_init(args);
diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
index 4e280b6ab9..ff45dcdc0d 100644
--- a/hw/intc/imx_avic.c
+++ b/hw/intc/imx_avic.c
@@ -370,7 +370,7 @@ static void imx_avic_reset(DeviceState *dev)
static int imx_avic_init(SysBusDevice *dev)
{
- IMXAVICState *s = FROM_SYSBUS(IMXAVICState, dev);;
+ IMXAVICState *s = FROM_SYSBUS(IMXAVICState, dev);
memory_region_init_io(&s->iomem, &imx_avic_ops, s, "imx_avic", 0x1000);
sysbus_init_mmio(dev, &s->iomem);
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9f18d6ab09..bed0822f0a 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1275,6 +1275,29 @@ void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
n->config_size = config_size;
}
+void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
+ const char *type)
+{
+ /*
+ * The name can be NULL, the netclient name will be type.x.
+ */
+ assert(type != NULL);
+
+ if (n->netclient_name) {
+ g_free(n->netclient_name);
+ n->netclient_name = NULL;
+ }
+ if (n->netclient_type) {
+ g_free(n->netclient_type);
+ n->netclient_type = NULL;
+ }
+
+ if (name != NULL) {
+ n->netclient_name = g_strdup(name);
+ }
+ n->netclient_type = g_strdup(type);
+}
+
static int virtio_net_device_init(VirtIODevice *vdev)
{
int i;
@@ -1315,8 +1338,17 @@ static int virtio_net_device_init(VirtIODevice *vdev)
memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac));
n->status = VIRTIO_NET_S_LINK_UP;
- n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
- object_get_typename(OBJECT(qdev)), qdev->id, n);
+ if (n->netclient_type) {
+ /*
+ * Happen when virtio_net_set_netclient_name has been called.
+ */
+ n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
+ n->netclient_type, n->netclient_name, n);
+ } else {
+ n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
+ object_get_typename(OBJECT(qdev)), qdev->id, n);
+ }
+
peer_test_vnet_hdr(n);
if (peer_has_vnet_hdr(n)) {
for (i = 0; i < n->max_queues; i++) {
@@ -1357,6 +1389,15 @@ static int virtio_net_device_exit(DeviceState *qdev)
unregister_savevm(qdev, "virtio-net", n);
+ if (n->netclient_name) {
+ g_free(n->netclient_name);
+ n->netclient_name = NULL;
+ }
+ if (n->netclient_type) {
+ g_free(n->netclient_type);
+ n->netclient_type = NULL;
+ }
+
g_free(n->mac_table.macs);
g_free(n->vlans);
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 540daf75cc..2f996d9549 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -28,6 +28,36 @@
* this allows a newer kernel to use the INTERRUPT_LINE
* registers arbitrarily once it has indicated that it isn't
* broken in its init code somewhere.
+ *
+ * Unfortunately we have to cope with multiple different
+ * variants on the broken kernel behaviour:
+ * phase I (before kernel commit 1bc39ac5d) kernels assume old
+ * QEMU behaviour, so they use IRQ 27 for all slots
+ * phase II (1bc39ac5d and later, but before e3e92a7be6) kernels
+ * swizzle IRQs between slots, but do it wrongly, so they
+ * work only for every fourth PCI card, and only if (like old
+ * QEMU) the PCI host device is at slot 0 rather than where
+ * the h/w actually puts it
+ * phase III (e3e92a7be6 and later) kernels still swizzle IRQs between
+ * slots wrongly, but add a fixed offset of 64 to everything
+ * they write to PCI_INTERRUPT_LINE.
+ *
+ * We live in hope of a mythical phase IV kernel which might
+ * actually behave in ways that work on the hardware. Such a
+ * kernel should probably start off by writing some value neither
+ * 27 nor 91 to slot zero's PCI_INTERRUPT_LINE register to
+ * disable the autodetection. After that it can do what it likes.
+ *
+ * Slot % 4 | hw | I | II | III
+ * -------------------------------
+ * 0 | 29 | 27 | 27 | 91
+ * 1 | 30 | 27 | 28 | 92
+ * 2 | 27 | 27 | 29 | 93
+ * 3 | 28 | 27 | 30 | 94
+ *
+ * Since our autodetection is not perfect we also provide a
+ * property so the user can make us start in BROKEN or FORCE_OK
+ * on reset if they know they have a bad or good kernel.
*/
enum {
PCI_VPB_IRQMAP_ASSUME_OK,
@@ -56,6 +86,7 @@ typedef struct {
/* Constant for life of device: */
int realview;
uint32_t mem_win_size[3];
+ uint8_t irq_mapping_prop;
/* Variable state: */
uint32_t imap[3];
@@ -214,6 +245,41 @@ static const MemoryRegionOps pci_vpb_reg_ops = {
},
};
+static int pci_vpb_broken_irq(int slot, int irq)
+{
+ /* Determine whether this IRQ value for this slot represents a
+ * known broken Linux kernel behaviour for this slot.
+ * Return one of the PCI_VPB_IRQMAP_ constants:
+ * BROKEN : if this definitely looks like a broken kernel
+ * FORCE_OK : if this definitely looks good
+ * ASSUME_OK : if we can't tell
+ */
+ slot %= PCI_NUM_PINS;
+
+ if (irq == 27) {
+ if (slot == 2) {
+ /* Might be a Phase I kernel, or might be a fixed kernel,
+ * since slot 2 is where we expect this IRQ.
+ */
+ return PCI_VPB_IRQMAP_ASSUME_OK;
+ }
+ /* Phase I kernel */
+ return PCI_VPB_IRQMAP_BROKEN;
+ }
+ if (irq == slot + 27) {
+ /* Phase II kernel */
+ return PCI_VPB_IRQMAP_BROKEN;
+ }
+ if (irq == slot + 27 + 64) {
+ /* Phase III kernel */
+ return PCI_VPB_IRQMAP_BROKEN;
+ }
+ /* Anything else must be a fixed kernel, possibly using an
+ * arbitrary irq map.
+ */
+ return PCI_VPB_IRQMAP_FORCE_OK;
+}
+
static void pci_vpb_config_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
@@ -221,13 +287,7 @@ static void pci_vpb_config_write(void *opaque, hwaddr addr,
if (!s->realview && (addr & 0xff) == PCI_INTERRUPT_LINE
&& s->irq_mapping == PCI_VPB_IRQMAP_ASSUME_OK) {
uint8_t devfn = addr >> 8;
- if ((PCI_SLOT(devfn) % PCI_NUM_PINS) != 2) {
- if (val == 27) {
- s->irq_mapping = PCI_VPB_IRQMAP_BROKEN;
- } else {
- s->irq_mapping = PCI_VPB_IRQMAP_FORCE_OK;
- }
- }
+ s->irq_mapping = pci_vpb_broken_irq(PCI_SLOT(devfn), val);
}
pci_data_write(&s->pci_bus, addr, val, size);
}
@@ -311,7 +371,7 @@ static void pci_vpb_reset(DeviceState *d)
s->smap[2] = 0;
s->selfid = 0;
s->flags = 0;
- s->irq_mapping = PCI_VPB_IRQMAP_ASSUME_OK;
+ s->irq_mapping = s->irq_mapping_prop;
pci_vpb_update_all_windows(s);
}
@@ -331,8 +391,6 @@ static void pci_vpb_init(Object *obj)
object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST);
qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
- object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(29, 0), "addr",
- NULL);
/* Window sizes for VersatilePB; realview_pci's init will override */
s->mem_win_size[0] = 0x0c000000;
@@ -423,6 +481,12 @@ static const TypeInfo versatile_pci_host_info = {
.class_init = versatile_pci_host_class_init,
};
+static Property pci_vpb_properties[] = {
+ DEFINE_PROP_UINT8("broken-irq-mapping", PCIVPBState, irq_mapping_prop,
+ PCI_VPB_IRQMAP_ASSUME_OK),
+ DEFINE_PROP_END_OF_LIST()
+};
+
static void pci_vpb_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -430,6 +494,7 @@ static void pci_vpb_class_init(ObjectClass *klass, void *data)
dc->realize = pci_vpb_realize;
dc->reset = pci_vpb_reset;
dc->vmsd = &pci_vpb_vmstate;
+ dc->props = pci_vpb_properties;
}
static const TypeInfo pci_vpb_info = {
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 5a3d97c037..a1cdfb0590 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -152,10 +152,13 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
{
+ DeviceState *qdev = DEVICE(s390_dev);
VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev);
DeviceState *vdev = DEVICE(&dev->vdev);
virtio_net_set_config_size(&dev->vdev, s390_dev->host_features);
+ virtio_net_set_netclient_name(&dev->vdev, qdev->id,
+ object_get_typename(OBJECT(qdev)));
qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
if (qdev_init(vdev) < 0) {
return -1;
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 76e6d32b72..5f5e267558 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -550,10 +550,13 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev)
static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
{
+ DeviceState *qdev = DEVICE(ccw_dev);
VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
DeviceState *vdev = DEVICE(&dev->vdev);
virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
+ virtio_net_set_netclient_name(&dev->vdev, qdev->id,
+ object_get_typename(OBJECT(qdev)));
qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
if (qdev_init(vdev) < 0) {
return -1;
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index 8994668dcd..ca09a891ee 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -651,7 +651,7 @@ static void usb_host_handle_reset(USBDevice *dev)
trace_usb_host_reset(s->bus_num, s->addr);
- usb_host_do_reset(s);;
+ usb_host_do_reset(s);
usb_host_claim_interfaces(s, 0);
usb_linux_update_endp_table(s);
@@ -1429,7 +1429,7 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
usb_host_release_port(s);
if (s->fd != -1) {
- usb_host_do_reset(s);;
+ usb_host_do_reset(s);
}
}
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index aab72ffb42..ea2e11ae95 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -154,12 +154,26 @@ void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config)
}
}
+static char *virtio_bus_get_dev_path(DeviceState *dev)
+{
+ BusState *bus = qdev_get_parent_bus(dev);
+ DeviceState *proxy = DEVICE(bus->parent);
+ return qdev_get_dev_path(proxy);
+}
+
+static void virtio_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *bus_class = BUS_CLASS(klass);
+ bus_class->get_dev_path = virtio_bus_get_dev_path;
+}
+
static const TypeInfo virtio_bus_info = {
.name = TYPE_VIRTIO_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(VirtioBusState),
.abstract = true,
.class_size = sizeof(VirtioBusClass),
+ .class_init = virtio_bus_class_init
};
static void virtio_register_types(void)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 113fbd9550..70d2c6b5e3 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1398,10 +1398,13 @@ static Property virtio_net_properties[] = {
static int virtio_net_pci_init(VirtIOPCIProxy *vpci_dev)
{
+ DeviceState *qdev = DEVICE(vpci_dev);
VirtIONetPCI *dev = VIRTIO_NET_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&dev->vdev);
virtio_net_set_config_size(&dev->vdev, vpci_dev->host_features);
+ virtio_net_set_netclient_name(&dev->vdev, qdev->id,
+ object_get_typename(OBJECT(qdev)));
qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
if (qdev_init(vdev) < 0) {
return -1;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 417afe4ef0..2bd7090248 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -169,7 +169,6 @@ static inline bool isa_ne2000_init(ISABus *bus, int base, int irq, NICInfo *nd)
}
/* pc_sysfw.c */
-extern bool pc_sysfw_flash_vs_rom_bug_compatible;
void pc_system_firmware_init(MemoryRegion *rom_memory);
/* pvpanic.c */
@@ -239,10 +238,6 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
.property = "romfile",\
.value = "pxe-virtio.rom",\
},{\
- .driver = "pc-sysfw",\
- .property = "rom_only",\
- .value = stringify(0),\
- },{\
.driver = "486-" TYPE_X86_CPU,\
.property = "model",\
.value = stringify(0),\
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index ce4ab50f67..beeead7a1a 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -188,6 +188,8 @@ typedef struct VirtIONet {
uint16_t max_queues;
uint16_t curr_queues;
size_t config_size;
+ char *netclient_name;
+ char *netclient_type;
} VirtIONet;
#define VIRTIO_NET_CTRL_MAC 1
@@ -255,5 +257,7 @@ struct virtio_net_ctrl_mq {
DEFINE_PROP_STRING("tx", _state, _field.tx)
void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features);
+void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
+ const char *type);
#endif
diff --git a/include/qemu-common.h b/include/qemu-common.h
index b399d855c1..7f18b8e1f9 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -42,6 +42,18 @@
#include <signal.h>
#include "glib-compat.h"
+#if defined(__GLIBC__)
+# include <pty.h>
+#elif defined CONFIG_BSD
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+# include <libutil.h>
+# else
+# include <util.h>
+# endif
+#elif defined CONFIG_SOLARIS
+# include <stropts.h>
+#endif
+
#ifdef _WIN32
#include "sysemu/os-win32.h"
#endif
@@ -436,12 +448,18 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
/* vector definitions */
#ifdef __ALTIVEC__
#include <altivec.h>
-#define VECTYPE vector unsigned char
+/* The altivec.h header says we're allowed to undef these for
+ * C++ compatibility. Here we don't care about C++, but we
+ * undef them anyway to avoid namespace pollution.
+ */
+#undef vector
+#undef pixel
+#undef bool
+#define VECTYPE __vector unsigned char
#define SPLAT(p) vec_splat(vec_ld(0, p), 0)
#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
/* altivec.h may redefine the bool macro as vector type.
* Reset it to POSIX semantics. */
-#undef bool
#define bool _Bool
#elif defined __SSE2__
#include <emmintrin.h>
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 42545bcbdb..57d7b1fb4d 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -5,8 +5,8 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
-#ifdef __OpenBSD__
#include <sys/types.h>
+#ifdef __OpenBSD__
#include <sys/signal.h>
#endif
@@ -96,8 +96,9 @@ typedef signed int int_fast16_t;
int qemu_daemon(int nochdir, int noclose);
void *qemu_memalign(size_t alignment, size_t size);
-void *qemu_vmalloc(size_t size);
+void *qemu_anon_ram_alloc(size_t size);
void qemu_vfree(void *ptr);
+void qemu_anon_ram_free(void *ptr, size_t size);
#define QEMU_MADV_INVALID -1
diff --git a/include/qom/object.h b/include/qom/object.h
index d0f99c5782..23fc048088 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -344,6 +344,8 @@ typedef void (ObjectUnparent)(Object *obj);
*/
typedef void (ObjectFree)(void *obj);
+#define OBJECT_CLASS_CAST_CACHE 4
+
/**
* ObjectClass:
*
@@ -356,6 +358,8 @@ struct ObjectClass
Type type;
GSList *interfaces;
+ const char *cast_cache[OBJECT_CLASS_CAST_CACHE];
+
ObjectUnparent *unparent;
};
@@ -476,7 +480,8 @@ struct TypeInfo
* generated.
*/
#define OBJECT_CHECK(type, obj, name) \
- ((type *)object_dynamic_cast_assert(OBJECT(obj), (name)))
+ ((type *)object_dynamic_cast_assert(OBJECT(obj), (name), \
+ __FILE__, __LINE__, __func__))
/**
* OBJECT_CLASS_CHECK:
@@ -489,7 +494,8 @@ struct TypeInfo
* specific class type.
*/
#define OBJECT_CLASS_CHECK(class, obj, name) \
- ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name)))
+ ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name), \
+ __FILE__, __LINE__, __func__))
/**
* OBJECT_GET_CLASS:
@@ -547,7 +553,8 @@ struct InterfaceClass
* Returns: @obj casted to @interface if cast is valid, otherwise raise error.
*/
#define INTERFACE_CHECK(interface, obj, name) \
- ((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name)))
+ ((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name), \
+ __FILE__, __LINE__, __func__))
/**
* object_new:
@@ -612,9 +619,12 @@ Object *object_dynamic_cast(Object *obj, const char *typename);
*
* See object_dynamic_cast() for a description of the parameters of this
* function. The only difference in behavior is that this function asserts
- * instead of returning #NULL on failure.
+ * instead of returning #NULL on failure if QOM cast debugging is enabled.
+ * This function is not meant to be called directly, but only through
+ * the wrapper macro OBJECT_CHECK.
*/
-Object *object_dynamic_cast_assert(Object *obj, const char *typename);
+Object *object_dynamic_cast_assert(Object *obj, const char *typename,
+ const char *file, int line, const char *func);
/**
* object_get_class:
@@ -659,11 +669,31 @@ Type type_register(const TypeInfo *info);
* @klass: The #ObjectClass to attempt to cast.
* @typename: The QOM typename of the class to cast to.
*
- * Returns: This function always returns @klass and asserts on failure.
+ * See object_class_dynamic_cast() for a description of the parameters
+ * of this function. The only difference in behavior is that this function
+ * asserts instead of returning #NULL on failure if QOM cast debugging is
+ * enabled. This function is not meant to be called directly, but only through
+ * the wrapper macros OBJECT_CLASS_CHECK and INTERFACE_CHECK.
*/
ObjectClass *object_class_dynamic_cast_assert(ObjectClass *klass,
- const char *typename);
+ const char *typename,
+ const char *file, int line,
+ const char *func);
+/**
+ * object_class_dynamic_cast:
+ * @klass: The #ObjectClass to attempt to cast.
+ * @typename: The QOM typename of the class to cast to.
+ *
+ * Returns: If @typename is a class, this function returns @klass if
+ * @typename is a subtype of @klass, else returns #NULL.
+ *
+ * If @typename is an interface, this function returns the interface
+ * definition for @klass if @klass implements it unambiguously; #NULL
+ * is returned if @klass does not implement the interface or if multiple
+ * classes or interfaces on the hierarchy leading to @klass implement
+ * it. (FIXME: perhaps this can be detected at type definition time?)
+ */
ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
const char *typename);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 9735c1dee6..08284ef770 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -142,8 +142,8 @@ int kvm_init_vcpu(CPUState *cpu);
int kvm_cpu_exec(CPUArchState *env);
#if !defined(CONFIG_USER_ONLY)
-void *kvm_vmalloc(ram_addr_t size);
-void *kvm_arch_vmalloc(ram_addr_t size);
+void *kvm_ram_alloc(ram_addr_t size);
+void *kvm_arch_ram_alloc(ram_addr_t size);
#endif
void kvm_setup_guest_memory(void *start, size_t size);
diff --git a/kvm-all.c b/kvm-all.c
index 3a31602359..8222729773 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1790,17 +1790,17 @@ int kvm_has_intx_set_mask(void)
return kvm_state->intx_set_mask;
}
-void *kvm_vmalloc(ram_addr_t size)
+void *kvm_ram_alloc(ram_addr_t size)
{
#ifdef TARGET_S390X
void *mem;
- mem = kvm_arch_vmalloc(size);
+ mem = kvm_arch_ram_alloc(size);
if (mem) {
return mem;
}
#endif
- return qemu_vmalloc(size);
+ return qemu_anon_ram_alloc(size);
}
void kvm_setup_guest_memory(void *start, size_t size)
diff --git a/main-loop.c b/main-loop.c
index f46aece8b8..cf36645af4 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -333,11 +333,11 @@ static int pollfds_fill(GArray *pollfds, fd_set *rfds, fd_set *wfds,
GPollFD *pfd = &g_array_index(pollfds, GPollFD, i);
int fd = pfd->fd;
int events = pfd->events;
- if (events & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
+ if (events & G_IO_IN) {
FD_SET(fd, rfds);
nfds = MAX(nfds, fd);
}
- if (events & (G_IO_OUT | G_IO_ERR)) {
+ if (events & G_IO_OUT) {
FD_SET(fd, wfds);
nfds = MAX(nfds, fd);
}
@@ -360,10 +360,10 @@ static void pollfds_poll(GArray *pollfds, int nfds, fd_set *rfds,
int revents = 0;
if (FD_ISSET(fd, rfds)) {
- revents |= G_IO_IN | G_IO_HUP | G_IO_ERR;
+ revents |= G_IO_IN;
}
if (FD_ISSET(fd, wfds)) {
- revents |= G_IO_OUT | G_IO_ERR;
+ revents |= G_IO_OUT;
}
if (FD_ISSET(fd, xfds)) {
revents |= G_IO_PRI;
@@ -394,6 +394,20 @@ static int os_host_main_loop_wait(uint32_t timeout)
return ret;
}
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&xfds);
+ nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
+ if (nfds >= 0) {
+ select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
+ if (select_ret != 0) {
+ timeout = 0;
+ }
+ if (select_ret > 0) {
+ pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
+ }
+ }
+
g_main_context_prepare(context, &max_priority);
n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
poll_fds, ARRAY_SIZE(poll_fds));
@@ -426,24 +440,6 @@ static int os_host_main_loop_wait(uint32_t timeout)
g_main_context_dispatch(context);
}
- /* Call select after g_poll to avoid a useless iteration and therefore
- * improve socket latency.
- */
-
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&xfds);
- nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
- if (nfds >= 0) {
- select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
- if (select_ret != 0) {
- timeout = 0;
- }
- if (select_ret > 0) {
- pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
- }
- }
-
return select_ret || g_poll_ret;
}
#endif
diff --git a/migration.c b/migration.c
index 3eb0fad147..bfbc34544a 100644
--- a/migration.c
+++ b/migration.c
@@ -498,7 +498,6 @@ static void *migration_thread(void *opaque)
{
MigrationState *s = opaque;
int64_t initial_time = qemu_get_clock_ms(rt_clock);
- int64_t sleep_time = 0;
int64_t initial_bytes = 0;
int64_t max_size = 0;
int64_t start_time = initial_time;
@@ -541,7 +540,7 @@ static void *migration_thread(void *opaque)
current_time = qemu_get_clock_ms(rt_clock);
if (current_time >= initial_time + BUFFER_DELAY) {
uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes;
- uint64_t time_spent = current_time - initial_time - sleep_time;
+ uint64_t time_spent = current_time - initial_time;
double bandwidth = transferred_bytes / time_spent;
max_size = bandwidth * migrate_max_downtime() / 1000000;
@@ -555,14 +554,12 @@ static void *migration_thread(void *opaque)
}
qemu_file_reset_rate_limit(s->file);
- sleep_time = 0;
initial_time = current_time;
initial_bytes = qemu_ftell(s->file);
}
if (qemu_file_rate_limit(s->file)) {
/* usleep expects microseconds */
g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);
- sleep_time += qemu_get_clock_ms(rt_clock) - current_time;
}
}
diff --git a/qemu-char.c b/qemu-char.c
index 64e824d0ac..30a2ddfb67 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -53,13 +53,6 @@
#include <sys/select.h>
#ifdef CONFIG_BSD
#include <sys/stat.h>
-#if defined(__GLIBC__)
-#include <pty.h>
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-#include <libutil.h>
-#else
-#include <util.h>
-#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
@@ -69,8 +62,6 @@
#endif
#else
#ifdef __linux__
-#include <pty.h>
-
#include <linux/ppdev.h>
#include <linux/parport.h>
#endif
@@ -87,7 +78,6 @@
#include <netinet/tcp.h>
#include <net/if.h>
#include <syslog.h>
-#include <stropts.h>
#endif
#endif
#endif
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 64493ebfce..5fc0eae400 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -214,10 +214,6 @@ PCI UHCI USB controller and a virtual USB hub.
SMP is supported with up to 255 CPUs.
-Note that adlib, gus and cs4231a are only available when QEMU was
-configured with --audio-card-list option containing the name(s) of
-required card(s).
-
QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
VGA BIOS.
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index 7ed98d72fb..8a303f35ec 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -268,7 +268,7 @@ static GIOStatus ga_channel_write(GAChannel *c, const char *buf, size_t size,
GIOStatus ga_channel_write_all(GAChannel *c, const char *buf, size_t size)
{
- GIOStatus status = G_IO_STATUS_NORMAL;;
+ GIOStatus status = G_IO_STATUS_NORMAL;
size_t count;
while (size) {
diff --git a/qom/object.c b/qom/object.c
index 75e6aac15f..ec88231fa9 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -16,6 +16,7 @@
#include "qapi/string-input-visitor.h"
#include "qapi/string-output-visitor.h"
#include "qapi/qmp/qerror.h"
+#include "trace.h"
/* TODO: replace QObject with a simpler visitor to avoid a dependency
* of the QOM core on QObject? */
@@ -431,28 +432,62 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
return NULL;
}
-Object *object_dynamic_cast_assert(Object *obj, const char *typename)
+Object *object_dynamic_cast_assert(Object *obj, const char *typename,
+ const char *file, int line, const char *func)
{
+ trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
+ typename, file, line, func);
+
+#ifdef CONFIG_QOM_CAST_DEBUG
+ int i;
Object *inst;
+ for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ if (obj->class->cast_cache[i] == typename) {
+ goto out;
+ }
+ }
+
inst = object_dynamic_cast(obj, typename);
if (!inst && obj) {
- fprintf(stderr, "Object %p is not an instance of type %s\n",
- obj, typename);
+ fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
+ file, line, func, obj, typename);
abort();
}
- return inst;
+ assert(obj == inst);
+
+ if (obj == inst) {
+ for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
+ }
+ obj->class->cast_cache[i - 1] = typename;
+ }
+
+out:
+#endif
+ return obj;
}
ObjectClass *object_class_dynamic_cast(ObjectClass *class,
const char *typename)
{
- TypeImpl *target_type = type_get_by_name(typename);
- TypeImpl *type = class->type;
ObjectClass *ret = NULL;
+ TypeImpl *target_type;
+ TypeImpl *type;
+
+ if (!class) {
+ return NULL;
+ }
+ /* A simple fast path that can trigger a lot for leaf classes. */
+ type = class->type;
+ if (type->name == typename) {
+ return class;
+ }
+
+ target_type = type_get_by_name(typename);
if (!target_type) {
/* target class type unknown, so fail the cast */
return NULL;
@@ -484,16 +519,46 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *class,
}
ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
- const char *typename)
+ const char *typename,
+ const char *file, int line,
+ const char *func)
{
- ObjectClass *ret = object_class_dynamic_cast(class, typename);
+ ObjectClass *ret;
- if (!ret) {
- fprintf(stderr, "Object %p is not an instance of type %s\n",
- class, typename);
+ trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
+ typename, file, line, func);
+
+#ifdef CONFIG_QOM_CAST_DEBUG
+ int i;
+
+ for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ if (class->cast_cache[i] == typename) {
+ ret = class;
+ goto out;
+ }
+ }
+#else
+ if (!class->interfaces) {
+ return class;
+ }
+#endif
+
+ ret = object_class_dynamic_cast(class, typename);
+ if (!ret && class) {
+ fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
+ file, line, func, class, typename);
abort();
}
+#ifdef CONFIG_QOM_CAST_DEBUG
+ if (ret == class) {
+ for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ class->cast_cache[i - 1] = class->cast_cache[i];
+ }
+ class->cast_cache[i - 1] = typename;
+ }
+out:
+#endif
return ret;
}
diff --git a/readline.c b/readline.c
index d6e04d4796..1c0f7ee26b 100644
--- a/readline.c
+++ b/readline.c
@@ -27,6 +27,7 @@
#define IS_NORM 0
#define IS_ESC 1
#define IS_CSI 2
+#define IS_SS3 3
#undef printf
#define printf do_not_use_printf
@@ -397,6 +398,9 @@ void readline_handle_byte(ReadLineState *rs, int ch)
if (ch == '[') {
rs->esc_state = IS_CSI;
rs->esc_param = 0;
+ } else if (ch == 'O') {
+ rs->esc_state = IS_SS3;
+ rs->esc_param = 0;
} else {
rs->esc_state = IS_NORM;
}
@@ -439,6 +443,17 @@ void readline_handle_byte(ReadLineState *rs, int ch)
rs->esc_state = IS_NORM;
the_end:
break;
+ case IS_SS3:
+ switch(ch) {
+ case 'F':
+ readline_eol(rs);
+ break;
+ case 'H':
+ readline_bol(rs);
+ break;
+ }
+ rs->esc_state = IS_NORM;
+ break;
}
readline_update(rs);
}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a585392b93..862fb12c84 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -332,7 +332,7 @@ static void *legacy_s390_alloc(ram_addr_t size)
return mem;
}
-void *kvm_arch_vmalloc(ram_addr_t size)
+void *kvm_arch_ram_alloc(ram_addr_t size)
{
/* Can we use the standard allocation ? */
if (kvm_check_extension(kvm_state, KVM_CAP_S390_GMAP) &&
diff --git a/tests/ide-test.c b/tests/ide-test.c
index bdc1da7dfe..365e9959ff 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -252,7 +252,10 @@ static void test_bmdma_simple_rw(void)
uintptr_t guest_buf = guest_alloc(guest_malloc, len);
PrdtEntry prdt[] = {
- { .addr = guest_buf, .size = len | PRDT_EOT },
+ {
+ .addr = cpu_to_le32(guest_buf),
+ .size = cpu_to_le32(len | PRDT_EOT),
+ },
};
buf = g_malloc(len);
@@ -304,7 +307,10 @@ static void test_bmdma_short_prdt(void)
uint8_t status;
PrdtEntry prdt[] = {
- { .addr = 0, .size = 0x10 | PRDT_EOT },
+ {
+ .addr = 0,
+ .size = cpu_to_le32(0x10 | PRDT_EOT),
+ },
};
/* Normal request */
@@ -325,7 +331,10 @@ static void test_bmdma_long_prdt(void)
uint8_t status;
PrdtEntry prdt[] = {
- { .addr = 0, .size = 0x1000 | PRDT_EOT },
+ {
+ .addr = 0,
+ .size = cpu_to_le32(0x1000 | PRDT_EOT),
+ },
};
/* Normal request */
@@ -355,6 +364,17 @@ static void test_bmdma_teardown(void)
ide_test_quit();
}
+static void string_cpu_to_be16(uint16_t *s, size_t bytes)
+{
+ g_assert((bytes & 1) == 0);
+ bytes /= 2;
+
+ while (bytes--) {
+ *s = cpu_to_be16(*s);
+ s++;
+ }
+}
+
static void test_identify(void)
{
uint8_t data;
@@ -389,10 +409,12 @@ static void test_identify(void)
assert_bit_clear(data, BSY | DF | ERR | DRQ);
/* Check serial number/version in the buffer */
- ret = memcmp(&buf[10], "ettsidks ", 20);
+ string_cpu_to_be16(&buf[10], 20);
+ ret = memcmp(&buf[10], "testdisk ", 20);
g_assert(ret == 0);
- ret = memcmp(&buf[23], "evsroi n", 8);
+ string_cpu_to_be16(&buf[23], 8);
+ ret = memcmp(&buf[23], "version ", 8);
g_assert(ret == 0);
/* Write cache enabled bit */
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index e84926f97c..8c8adac6a9 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -657,11 +657,16 @@ static void qmp_deserialize(void **native_out, void *datap,
VisitorFunc visit, Error **errp)
{
QmpSerializeData *d = datap;
- QString *output_json = qobject_to_json(qmp_output_get_qobject(d->qov));
- QObject *obj = qobject_from_json(qstring_get_str(output_json));
+ QString *output_json;
+ QObject *obj_orig, *obj;
+
+ obj_orig = qmp_output_get_qobject(d->qov);
+ output_json = qobject_to_json(obj_orig);
+ obj = qobject_from_json(qstring_get_str(output_json));
QDECREF(output_json);
d->qiv = qmp_input_visitor_new(obj);
+ qobject_decref(obj_orig);
qobject_decref(obj);
visit(qmp_input_get_visitor(d->qiv), native_out, errp);
}
diff --git a/trace-events b/trace-events
index 17d75abfe8..c03b9cb2cd 100644
--- a/trace-events
+++ b/trace-events
@@ -32,8 +32,9 @@ g_free(void *ptr) "ptr %p"
# osdep.c
qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
-qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
+qemu_anon_ram_alloc(size_t size, void *ptr) "size %zu ptr %p"
qemu_vfree(void *ptr) "ptr %p"
+qemu_anon_ram_free(void *ptr, size_t size) "size %zu ptr %p"
# hw/virtio.c
virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
@@ -1160,3 +1161,6 @@ kvm_vm_ioctl(int type, void *arg) "type %d, arg %p"
kvm_vcpu_ioctl(int cpu_index, int type, void *arg) "cpu_index %d, type %d, arg %p"
kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d"
+# qom/object.c
+object_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
+object_class_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
diff --git a/ui/gtk.c b/ui/gtk.c
index e12f22838e..52c3f95ffb 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -55,7 +55,6 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
-#include <pty.h>
#include <math.h>
#include "ui/console.h"
@@ -331,6 +330,24 @@ static void gd_refresh(DisplayChangeListener *dcl)
graphic_hw_update(dcl->con);
}
+#if GTK_CHECK_VERSION(3, 0, 0)
+static void gd_mouse_set(DisplayChangeListener *dcl,
+ int x, int y, int visible)
+{
+ GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
+ GdkDisplay *dpy;
+ GdkDeviceManager *mgr;
+ gint x_root, y_root;
+
+ dpy = gtk_widget_get_display(s->drawing_area);
+ mgr = gdk_display_get_device_manager(dpy);
+ gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
+ x, y, &x_root, &y_root);
+ gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
+ gtk_widget_get_screen(s->drawing_area),
+ x, y);
+}
+#else
static void gd_mouse_set(DisplayChangeListener *dcl,
int x, int y, int visible)
{
@@ -343,6 +360,7 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
gtk_widget_get_screen(s->drawing_area),
x_root, y_root);
}
+#endif
static void gd_cursor_define(DisplayChangeListener *dcl,
QEMUCursor *c)
diff --git a/ui/vnc.c b/ui/vnc.c
index 89108de223..dfc74591f4 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1601,6 +1601,7 @@ static void kbd_leds(void *opaque, int ledstate)
{
VncState *vs = opaque;
int caps, num, scr;
+ bool has_changed = (ledstate != current_led_state(vs));
caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
@@ -1617,7 +1618,7 @@ static void kbd_leds(void *opaque, int ledstate)
}
/* Sending the current led state message to the client */
- if (ledstate != current_led_state(vs)) {
+ if (has_changed) {
vnc_led_state_change(vs);
}
}
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 3efc76320a..631a1dea33 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -101,7 +101,7 @@ void *qemu_memalign(size_t alignment, size_t size)
}
/* alloc shared memory pages */
-void *qemu_vmalloc(size_t size)
+void *qemu_anon_ram_alloc(size_t size)
{
size_t align = QEMU_VMALLOC_ALIGN;
size_t total = size + align - getpagesize();
@@ -125,7 +125,7 @@ void *qemu_vmalloc(size_t size)
munmap(ptr + size, total - size);
}
- trace_qemu_vmalloc(size, ptr);
+ trace_qemu_anon_ram_alloc(size, ptr);
return ptr;
}
@@ -135,6 +135,14 @@ void qemu_vfree(void *ptr)
free(ptr);
}
+void qemu_anon_ram_free(void *ptr, size_t size)
+{
+ trace_qemu_anon_ram_free(ptr, size);
+ if (ptr) {
+ munmap(ptr, size);
+ }
+}
+
void qemu_set_block(int fd)
{
int f;
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index dcfa0c2918..df2ecbdffb 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -53,7 +53,7 @@ void *qemu_memalign(size_t alignment, size_t size)
return ptr;
}
-void *qemu_vmalloc(size_t size)
+void *qemu_anon_ram_alloc(size_t size)
{
void *ptr;
@@ -64,7 +64,7 @@ void *qemu_vmalloc(size_t size)
abort();
}
ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
- trace_qemu_vmalloc(size, ptr);
+ trace_qemu_anon_ram_alloc(size, ptr);
return ptr;
}
@@ -76,6 +76,14 @@ void qemu_vfree(void *ptr)
}
}
+void qemu_anon_ram_free(void *ptr, size_t size)
+{
+ trace_qemu_anon_ram_free(ptr, size);
+ if (ptr) {
+ VirtualFree(ptr, 0, MEM_RELEASE);
+ }
+}
+
/* FIXME: add proper locking */
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
diff --git a/util/uri.c b/util/uri.c
index 4238729b83..e348c1768c 100644
--- a/util/uri.c
+++ b/util/uri.c
@@ -2162,7 +2162,7 @@ query_params_append (struct QueryParams *ps,
}
ps->p[ps->n].name = g_strdup(name);
- ps->p[ps->n].value = value ? g_strdup(value) : NULL;
+ ps->p[ps->n].value = g_strdup(value);
ps->p[ps->n].ignore = 0;
ps->n++;
diff --git a/vl.c b/vl.c
index 6e6225f09b..be0a93c53d 100644
--- a/vl.c
+++ b/vl.c
@@ -1215,7 +1215,7 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
node = g_malloc0(sizeof(FWBootEntry));
node->bootindex = bootindex;
- node->suffix = suffix ? g_strdup(suffix) : NULL;
+ node->suffix = g_strdup(suffix);
node->dev = dev;
QTAILQ_FOREACH(i, &fw_boot_order, link) {