From: Anthony Liguori Date: Fri, 17 May 2013 15:00:30 +0000 (-0500) Subject: Merge remote-tracking branch 'mdroth/qga-pull-2013-05-13' into staging X-Git-Tag: v2.7.1~2737 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=ce4cc31695ee7e647ef5a3a3c1258089794dcb83;hp=2b720018060179b394f8ce736983373ab80dd37c;p=mirror_qemu.git Merge remote-tracking branch 'mdroth/qga-pull-2013-05-13' into staging * mdroth/qga-pull-2013-05-13: qga: unlink just created guest-file if fchmod() or fdopen() fails on it qga: distinguish binary modes in "guest_file_open_modes" map Signed-off-by: Anthony Liguori --- 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 */ @@ -238,10 +237,6 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); .driver = "virtio-net-pci",\ .property = "romfile",\ .value = "pxe-virtio.rom",\ - },{\ - .driver = "pc-sysfw",\ - .property = "rom_only",\ - .value = stringify(0),\ },{\ .driver = "486-" TYPE_X86_CPU,\ .property = "model",\ 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 #include "glib-compat.h" +#if defined(__GLIBC__) +# include +#elif defined CONFIG_BSD +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +# include +# else +# include +# endif +#elif defined CONFIG_SOLARIS +# include +#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 -#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 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 #include #include -#ifdef __OpenBSD__ #include +#ifdef __OpenBSD__ #include #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 #ifdef CONFIG_BSD #include -#if defined(__GLIBC__) -#include -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -#include -#else -#include -#endif #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include #include @@ -69,8 +62,6 @@ #endif #else #ifdef __linux__ -#include - #include #include #endif @@ -87,7 +78,6 @@ #include #include #include -#include #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 #include #include -#include #include #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) {