aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c24
-rw-r--r--block/qapi.c3
-rw-r--r--chardev/char-fd.c1
-rw-r--r--chardev/char.c2
-rw-r--r--exec.c12
-rw-r--r--hw/bt/sdp.c17
-rw-r--r--hw/scsi/vmw_pvscsi.c12
-rw-r--r--hw/timer/mc146818rtc.c37
-rw-r--r--include/chardev/char-fd.h2
-rw-r--r--include/chardev/char.h4
-rw-r--r--include/exec/ram_addr.h7
-rw-r--r--memory.c36
-rw-r--r--qemu-doc.texi175
-rw-r--r--qemu-options.hx15
-rw-r--r--target/i386/kvm.c35
-rwxr-xr-xtests/qemu-iotests/0414
-rwxr-xr-xtests/qemu-iotests/05911
-rw-r--r--tests/qemu-iotests/059.out22
-rwxr-xr-xtests/qemu-iotests/0634
-rwxr-xr-xtests/qemu-iotests/0741
-rw-r--r--tests/qemu-iotests/1247
-rwxr-xr-xtests/qemu-iotests/1412
-rwxr-xr-xtests/qemu-iotests/1531
-rwxr-xr-xtests/qemu-iotests/1564
-rwxr-xr-xtests/qemu-iotests/1627
-rwxr-xr-xtests/qemu-iotests/1791
-rwxr-xr-xtests/qemu-iotests/1862
-rw-r--r--tests/qemu-iotests/186.out12
-rwxr-xr-xtests/qemu-iotests/19059
-rw-r--r--tests/qemu-iotests/190.out11
-rw-r--r--tests/qemu-iotests/common.rc3
-rw-r--r--tests/qemu-iotests/group1
-rw-r--r--tests/rtc-test.c156
-rw-r--r--vl.c12
34 files changed, 567 insertions, 135 deletions
diff --git a/block.c b/block.c
index 37e72b7..ce9cce7 100644
--- a/block.c
+++ b/block.c
@@ -1119,20 +1119,19 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
} else {
error_setg_errno(errp, -ret, "Could not open image");
}
- goto free_and_fail;
+ goto open_failed;
}
ret = refresh_total_sectors(bs, bs->total_sectors);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not refresh total sector count");
- goto free_and_fail;
+ return ret;
}
bdrv_refresh_limits(bs, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- ret = -EINVAL;
- goto free_and_fail;
+ return -EINVAL;
}
assert(bdrv_opt_mem_align(bs) != 0);
@@ -1140,12 +1139,14 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
assert(is_power_of_2(bs->bl.request_alignment));
return 0;
-
-free_and_fail:
- /* FIXME Close bs first if already opened*/
+open_failed:
+ bs->drv = NULL;
+ if (bs->file != NULL) {
+ bdrv_unref_child(bs, bs->file);
+ bs->file = NULL;
+ }
g_free(bs->opaque);
bs->opaque = NULL;
- bs->drv = NULL;
return ret;
}
@@ -1166,7 +1167,9 @@ BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
ret = bdrv_open_driver(bs, drv, node_name, bs->options, flags, errp);
if (ret < 0) {
QDECREF(bs->explicit_options);
+ bs->explicit_options = NULL;
QDECREF(bs->options);
+ bs->options = NULL;
bdrv_unref(bs);
return NULL;
}
@@ -2600,14 +2603,12 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
fail:
blk_unref(file);
- if (bs->file != NULL) {
- bdrv_unref_child(bs, bs->file);
- }
QDECREF(snapshot_options);
QDECREF(bs->explicit_options);
QDECREF(bs->options);
QDECREF(options);
bs->options = NULL;
+ bs->explicit_options = NULL;
bdrv_unref(bs);
error_propagate(errp, local_err);
return NULL;
@@ -3087,6 +3088,7 @@ static void bdrv_close(BlockDriverState *bs)
QDECREF(bs->options);
QDECREF(bs->explicit_options);
bs->options = NULL;
+ bs->explicit_options = NULL;
QDECREF(bs->full_open_options);
bs->full_open_options = NULL;
}
diff --git a/block/qapi.c b/block/qapi.c
index d2b18ee..5f1a71f 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -145,8 +145,9 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
/* Skip automatically inserted nodes that the user isn't aware of for
* query-block (blk != NULL), but not for query-named-block-nodes */
- while (blk && bs0 && bs0->drv && bs0->implicit) {
+ while (blk && bs0->drv && bs0->implicit) {
bs0 = backing_bs(bs0);
+ assert(bs0);
}
}
diff --git a/chardev/char-fd.c b/chardev/char-fd.c
index 1584a3d..6a62a54 100644
--- a/chardev/char-fd.c
+++ b/chardev/char-fd.c
@@ -141,7 +141,6 @@ void qemu_chr_open_fd(Chardev *chr,
qio_channel_set_name(QIO_CHANNEL(s->ioc_out), name);
g_free(name);
qemu_set_nonblock(fd_out);
- s->chr = chr;
}
static void char_fd_class_init(ObjectClass *oc, void *data)
diff --git a/chardev/char.c b/chardev/char.c
index c34b44a..5d283b9 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -620,7 +620,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error **errp)
error_report("Available chardev backend types: %s", str->str);
g_string_free(str, true);
- exit(0);
+ return NULL;
}
if (id == NULL) {
diff --git a/exec.c b/exec.c
index 01ac21e..d20c34c 100644
--- a/exec.c
+++ b/exec.c
@@ -2203,7 +2203,7 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
* Called within RCU critical section.
*/
static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
- hwaddr *size)
+ hwaddr *size, bool lock)
{
RAMBlock *block = ram_block;
if (*size == 0) {
@@ -2222,10 +2222,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
* In that case just map the requested area.
*/
if (block->offset == 0) {
- return xen_map_cache(addr, *size, 1, true);
+ return xen_map_cache(addr, *size, lock, lock);
}
- block->host = xen_map_cache(block->offset, block->max_length, 1, true);
+ block->host = xen_map_cache(block->offset, block->max_length, 1, lock);
}
return ramblock_ptr(block, addr);
@@ -2947,7 +2947,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
- ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(mr, addr1, l);
}
@@ -3038,7 +3038,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
- ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
memcpy(buf, ptr, l);
}
@@ -3349,7 +3349,7 @@ void *address_space_map(AddressSpace *as,
memory_region_ref(mr);
*plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write);
- ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen);
+ ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
rcu_read_unlock();
return ptr;
diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c
index f67b3b8..3cb60b9 100644
--- a/hw/bt/sdp.c
+++ b/hw/bt/sdp.c
@@ -580,7 +580,7 @@ static void bt_l2cap_sdp_close_ch(void *opaque)
int i;
for (i = 0; i < sdp->services; i ++) {
- g_free(sdp->service_list[i].attribute_list->pair);
+ g_free(sdp->service_list[i].attribute_list[0].pair);
g_free(sdp->service_list[i].attribute_list);
g_free(sdp->service_list[i].uuid);
}
@@ -720,6 +720,8 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
len += sdp_attr_max_size(&def->attributes[record->attributes ++].data,
&record->uuids);
}
+
+ assert(len > 0);
record->uuids = pow2ceil(record->uuids);
record->attribute_list =
g_malloc0(record->attributes * sizeof(*record->attribute_list));
@@ -730,12 +732,14 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
record->attributes = 0;
uuid = record->uuid;
while (def->attributes[record->attributes].data.type) {
+ int attribute_id = def->attributes[record->attributes].id;
record->attribute_list[record->attributes].pair = data;
+ record->attribute_list[record->attributes].attribute_id = attribute_id;
len = 0;
data[len ++] = SDP_DTYPE_UINT | SDP_DSIZE_2;
- data[len ++] = def->attributes[record->attributes].id >> 8;
- data[len ++] = def->attributes[record->attributes].id & 0xff;
+ data[len ++] = attribute_id >> 8;
+ data[len ++] = attribute_id & 0xff;
len += sdp_attr_write(data + len,
&def->attributes[record->attributes].data, &uuid);
@@ -749,10 +753,15 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
data += len;
}
- /* Sort the attribute list by the AttributeID */
+ /* Sort the attribute list by the AttributeID. The first must be
+ * SDP_ATTR_RECORD_HANDLE so that bt_l2cap_sdp_close_ch can free
+ * the buffer.
+ */
qsort(record->attribute_list, record->attributes,
sizeof(*record->attribute_list),
(void *) sdp_attributeid_compare);
+ assert(record->attribute_list[0].pair == data);
+
/* Sort the searchable UUIDs list for bisection */
qsort(record->uuid, record->uuids,
sizeof(*record->uuid),
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 4a106da..77d8b6f 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1103,8 +1103,8 @@ static const struct SCSIBusInfo pvscsi_scsi_info = {
.cancel = pvscsi_request_cancelled,
};
-static int
-pvscsi_init(PCIDevice *pci_dev)
+static void
+pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
{
PVSCSIState *s = PVSCSI(pci_dev);
@@ -1138,18 +1138,12 @@ pvscsi_init(PCIDevice *pci_dev)
}
s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
- if (!s->completion_worker) {
- pvscsi_cleanup_msi(s);
- return -ENOMEM;
- }
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
&pvscsi_scsi_info, NULL);
/* override default SCSI bus hotplug-handler, with pvscsi's one */
qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(s), &error_abort);
pvscsi_reset_state(s);
-
- return 0;
}
static void
@@ -1282,7 +1276,7 @@ static void pvscsi_class_init(ObjectClass *klass, void *data)
PVSCSIClass *pvs_k = PVSCSI_DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
- k->init = pvscsi_init;
+ k->realize = pvscsi_realizefn;
k->exit = pvscsi_uninit;
k->vendor_id = PCI_VENDOR_ID_VMWARE;
k->device_id = PCI_DEVICE_ID_VMWARE_PVSCSI;
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 1b8d3d7..82843ed 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -291,26 +291,15 @@ static void check_update_timer(RTCState *s)
/* From the data sheet: "Holding the dividers in reset prevents
* interrupts from operating, while setting the SET bit allows"
- * them to occur. However, it will prevent an alarm interrupt
- * from occurring, because the time of day is not updated.
+ * them to occur.
*/
if ((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) {
- timer_del(s->update_timer);
- return;
- }
- if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
- (s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- timer_del(s->update_timer);
- return;
- }
- if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
- (s->cmos_data[RTC_REG_C] & REG_C_AF)) {
+ assert((s->cmos_data[RTC_REG_A] & REG_A_UIP) == 0);
timer_del(s->update_timer);
return;
}
guest_nsec = get_guest_rtc_ns(s) % NANOSECONDS_PER_SECOND;
- /* if UF is clear, reprogram to next second */
next_update_time = qemu_clock_get_ns(rtc_clock)
+ NANOSECONDS_PER_SECOND - guest_nsec;
@@ -321,7 +310,21 @@ static void check_update_timer(RTCState *s)
s->next_alarm_time = next_update_time +
(next_alarm_sec - 1) * NANOSECONDS_PER_SECOND;
- if (s->cmos_data[RTC_REG_C] & REG_C_UF) {
+ /* If update_in_progress latched the UIP bit, we must keep the timer
+ * programmed to the next second, so that UIP is cleared. Otherwise,
+ * if UF is already set, we might be able to optimize.
+ */
+ if (!(s->cmos_data[RTC_REG_A] & REG_A_UIP) &&
+ (s->cmos_data[RTC_REG_C] & REG_C_UF)) {
+ /* If AF cannot change (i.e. either it is set already, or
+ * SET=1 and then the time is not updated), nothing to do.
+ */
+ if ((s->cmos_data[RTC_REG_B] & REG_B_SET) ||
+ (s->cmos_data[RTC_REG_C] & REG_C_AF)) {
+ timer_del(s->update_timer);
+ return;
+ }
+
/* UF is set, but AF is clear. Program the timer to target
* the alarm time. */
next_update_time = s->next_alarm_time;
@@ -727,12 +730,10 @@ static uint64_t cmos_ioport_read(void *opaque, hwaddr addr,
ret = s->cmos_data[s->cmos_index];
break;
case RTC_REG_A:
+ ret = s->cmos_data[s->cmos_index];
if (update_in_progress(s)) {
- s->cmos_data[s->cmos_index] |= REG_A_UIP;
- } else {
- s->cmos_data[s->cmos_index] &= ~REG_A_UIP;
+ ret |= REG_A_UIP;
}
- ret = s->cmos_data[s->cmos_index];
break;
case RTC_REG_C:
ret = s->cmos_data[s->cmos_index];
diff --git a/include/chardev/char-fd.h b/include/chardev/char-fd.h
index 55ae5b4..e7c2b17 100644
--- a/include/chardev/char-fd.h
+++ b/include/chardev/char-fd.h
@@ -29,7 +29,7 @@
typedef struct FDChardev {
Chardev parent;
- Chardev *chr;
+
QIOChannel *ioc_in, *ioc_out;
int max_size;
} FDChardev;
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 1604ea9..66dde46 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -65,7 +65,9 @@ struct Chardev {
*
* @opts see qemu-config.c for a list of valid options
*
- * Returns: a new character backend
+ * Returns: on success: a new character backend
+ * otherwise: NULL; @errp specifies the error
+ * or left untouched in case of help option
*/
Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
Error **errp);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index c04f4f6..d017639 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -377,19 +377,20 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
uint64_t *real_dirty_pages)
{
ram_addr_t addr;
- unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS);
+ unsigned long word = BIT_WORD((start + rb->offset) >> TARGET_PAGE_BITS);
uint64_t num_dirty = 0;
unsigned long *dest = rb->bmap;
/* start address is aligned at the start of a word? */
- if (((page * BITS_PER_LONG) << TARGET_PAGE_BITS) == start) {
+ if (((word * BITS_PER_LONG) << TARGET_PAGE_BITS) ==
+ (start + rb->offset)) {
int k;
int nr = BITS_TO_LONGS(length >> TARGET_PAGE_BITS);
unsigned long * const *src;
- unsigned long word = BIT_WORD((start + rb->offset) >> TARGET_PAGE_BITS);
unsigned long idx = (word * BITS_PER_LONG) / DIRTY_MEMORY_BLOCK_SIZE;
unsigned long offset = BIT_WORD((word * BITS_PER_LONG) %
DIRTY_MEMORY_BLOCK_SIZE);
+ unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS);
rcu_read_lock();
diff --git a/memory.c b/memory.c
index a7bc70a..c0adc35 100644
--- a/memory.c
+++ b/memory.c
@@ -2357,8 +2357,15 @@ void memory_global_dirty_log_sync(void)
}
}
+static VMChangeStateEntry *vmstate_change;
+
void memory_global_dirty_log_start(void)
{
+ if (vmstate_change) {
+ qemu_del_vm_change_state_handler(vmstate_change);
+ vmstate_change = NULL;
+ }
+
global_dirty_log = true;
MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward);
@@ -2369,7 +2376,7 @@ void memory_global_dirty_log_start(void)
memory_region_transaction_commit();
}
-void memory_global_dirty_log_stop(void)
+static void memory_global_dirty_log_do_stop(void)
{
global_dirty_log = false;
@@ -2381,6 +2388,33 @@ void memory_global_dirty_log_stop(void)
MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
}
+static void memory_vm_change_state_handler(void *opaque, int running,
+ RunState state)
+{
+ if (running) {
+ memory_global_dirty_log_do_stop();
+
+ if (vmstate_change) {
+ qemu_del_vm_change_state_handler(vmstate_change);
+ vmstate_change = NULL;
+ }
+ }
+}
+
+void memory_global_dirty_log_stop(void)
+{
+ if (!runstate_is_running()) {
+ if (vmstate_change) {
+ return;
+ }
+ vmstate_change = qemu_add_vm_change_state_handler(
+ memory_vm_change_state_handler, NULL);
+ return;
+ }
+
+ memory_global_dirty_log_do_stop();
+}
+
static void listener_add_address_space(MemoryListener *listener,
AddressSpace *as)
{
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 48af515..aeb7bc5 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -38,6 +38,7 @@
* QEMU Guest Agent::
* QEMU User space emulator::
* Implementation notes::
+* Deprecated features::
* License::
* Index::
@end menu
@@ -3128,6 +3129,180 @@ Run the emulation in single step mode.
@include qemu-tech.texi
+@node Deprecated features
+@appendix Deprecated features
+
+In general features are intended to be supported indefinitely once
+introduced into QEMU. In the event that a feature needs to be removed,
+it will be listed in this appendix. The feature will remain functional
+for 2 releases prior to actual removal. Deprecated features may also
+generate warnings on the console when QEMU starts up, or if activated
+via a monitor command, however, this is not a mandatory requirement.
+
+Prior to the 2.10.0 release there was no official policy on how
+long features would be deprecated prior to their removal, nor
+any documented list of which features were deprecated. Thus
+any features deprecated prior to 2.10.0 will be treated as if
+they were first deprecated in the 2.10.0 release.
+
+What follows is a list of all features currently marked as
+deprecated.
+
+@section System emulator command line arguments
+
+@subsection -drive boot=on|off (since 1.3.0)
+
+The ``boot=on|off'' option to the ``-drive'' argument is
+ignored. Applications should use the ``bootindex=N'' parameter
+to set an absolute ordering between devices instead.
+
+@subsection -tdf (since 1.3.0)
+
+The ``-tdf'' argument is ignored. The behaviour implemented
+by this argument is now the default when using the KVM PIT,
+but can be requested explicitly using
+``-global kvm-pit.lost_tick_policy=slew''.
+
+@subsection -no-kvm-pit-reinjection (since 1.3.0)
+
+The ``-no-kvm-pit-reinjection'' argument is now a
+synonym for setting ``-global kvm-pit.lost_tick_policy=discard''.
+
+@subsection -no-kvm-irqchip (since 1.3.0)
+
+The ``-no-kvm-irqchip'' argument is now a synonym for
+setting ``-machine kernel_irqchip=off''.
+
+@subsection -no-kvm-pit (since 1.3.0)
+
+The ``-no-kvm-pit'' argument is ignored. It is no longer
+possible to disable the KVM PIT directly.
+
+@subsection -no-kvm (since 1.3.0)
+
+The ``-no-kvm'' argument is now a synonym for setting
+``-machine accel=tcg''.
+
+@subsection -mon default=on (since 2.4.0)
+
+The ``default'' option to the ``-mon'' argument is
+now ignored. When multiple monitors were enabled, it
+indicated which monitor would receive log messages
+from the various subsystems. This feature is no longer
+required as messages are now only sent to the monitor
+in response to explicitly monitor commands.
+
+@subsection -vnc tls (since 2.5.0)
+
+The ``-vnc tls'' argument is now a synonym for setting
+``-object tls-creds-anon,id=tls0'' combined with
+``-vnc tls-creds=tls0'
+
+@subsection -vnc x509 (since 2.5.0)
+
+The ``-vnc x509=/path/to/certs'' argument is now a
+synonym for setting
+``-object tls-creds-x509,dir=/path/to/certs,id=tls0,verify-peer=no''
+combined with ``-vnc tls-creds=tls0'
+
+@subsection -vnc x509verify (since 2.5.0)
+
+The ``-vnc x509verify=/path/to/certs'' argument is now a
+synonym for setting
+``-object tls-creds-x509,dir=/path/to/certs,id=tls0,verify-peer=yes''
+combined with ``-vnc tls-creds=tls0'
+
+@subsection -tftp (since 2.6.0)
+
+The ``-tftp /some/dir'' argument is now a synonym for setting
+the ``-netdev user,tftp=/some/dir' argument. The new syntax
+allows different settings to be provided per NIC.
+
+@subsection -bootp (since 2.6.0)
+
+The ``-bootp /some/file'' argument is now a synonym for setting
+the ``-netdev user,bootp=/some/file' argument. The new syntax
+allows different settings to be provided per NIC.
+
+@subsection -redir (since 2.6.0)
+
+The ``-redir ARGS'' argument is now a synonym for setting
+the ``-netdev user,hostfwd=ARGS'' argument instead. The new
+syntax allows different settings to be provided per NIC.
+
+@subsection -smb (since 2.6.0)
+
+The ``-smb /some/dir'' argument is now a synonym for setting
+the ``-netdev user,smb=/some/dir'' argument instead. The new
+syntax allows different settings to be provided per NIC.
+
+@subsection -net channel (since 2.6.0)
+
+The ``--net channel,ARGS'' argument is now a synonym for setting
+the ``-netdev user,guestfwd=ARGS'' argument instead.
+
+@subsection -net vlan (since 2.9.0)
+
+The ``-net van=NN'' argument is partially replaced with the
+new ``-netdev'' argument. The remaining use cases will no
+longer be directly supported in QEMU.
+
+@subsection -drive if=scsi (since 2.9.0)
+
+The ``-drive if=scsi'' argument is replaced by the the
+``-device BUS-TYPE'' argument combined with ``-drive if=none''.
+
+@subsection -net dump (since 2.10.0)
+
+The ``--net dump'' argument is now replaced with the
+``-object filter-dump'' argument which works in combination
+with the modern ``-netdev`` backends instead.
+
+@subsection -hdachs (since 2.10.0)
+
+The ``-hdachs'' argument is now a synonym for setting
+the ``cyls'', ``heads'', ``secs'', and ``trans'' properties
+on the ``ide-hd'' device using the ``-device'' argument.
+The new syntax allows different settings to be provided
+per disk.
+
+@subsection -usbdevice (since 2.10.0)
+
+The ``-usbdevice DEV'' argument is now a synonym for setting
+the ``-device usb-DEV'' argument instead. The deprecated syntax
+would automatically enable USB support on the machine type.
+If using the new syntax, USB support must be explicitly
+enabled via the ``-machine usb=on'' argument.
+
+@section qemu-img command line arguments
+
+@subsection convert -s (since 2.0.0)
+
+The ``convert -s snapshot_id_or_name'' argument is obsoleted
+by the ``convert -l snapshot_param'' argument instead.
+
+@section System emulator human monitor commands
+
+@subsection usb_add (since 2.10.0)
+
+The ``usb_add'' command is replaced by the ``device_add'' command.
+
+@subsection usb_del (since 2.10.0)
+
+The ``usb_del'' command is replaced by the ``device_del'' command.
+
+@section System emulator devices
+
+@subsection ivshmem (since 2.6.0)
+
+The ``ivshmem'' device type is replaced by either the ``ivshmem-plain''
+or ``ivshmem-doorbell`` device types.
+
+@subsection spapr-pci-vfio-host-bridge (since 2.6.0)
+
+The ``spapr-pci-vfio-host-bridge'' device type is replaced by
+the ``spapr-pci-host-bridge'' device type.
+
@node License
@appendix License
diff --git a/qemu-options.hx b/qemu-options.hx
index 746b5fa..9f6e2ad 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -49,7 +49,20 @@ STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
@findex -machine
Select the emulated machine by @var{name}. Use @code{-machine help} to list
-available machines. Supported machine properties are:
+available machines.
+
+For architectures which aim to support live migration compatibility
+across releases, each release will introduce a new versioned machine
+type. For example, the 2.8.0 release introduced machine types
+``pc-i440fx-2.8'' and ``pc-q35-2.8'' for the x86_64/i686 architectures.
+
+To allow live migration of guests from QEMU version 2.8.0, to QEMU
+version 2.9.0, the 2.9.0 version must support the ``pc-i440fx-2.8''
+and ``pc-q35-2.8'' machines too. To allow users live migrating VMs
+to skip multiple intermediate releases when upgrading, new releases
+of QEMU will support machine types from many previous versions.
+
+Supported machine properties are:
@table @option
@item accel=@var{accels1}[:@var{accels2}[:...]]
This is used to enable an accelerator. Depending on the target architecture,
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index a6613e1..6db7783 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -2444,8 +2444,10 @@ static int kvm_put_vcpu_events(X86CPU *cpu, int level)
}
if (level >= KVM_PUT_RESET_STATE) {
- events.flags |=
- KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR;
+ events.flags |= KVM_VCPUEVENT_VALID_NMI_PENDING;
+ if (env->mp_state == KVM_MP_STATE_SIPI_RECEIVED) {
+ events.flags |= KVM_VCPUEVENT_VALID_SIPI_VECTOR;
+ }
}
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events);
@@ -2633,6 +2635,10 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
if (ret < 0) {
return ret;
}
+ ret = kvm_put_vcpu_events(x86_cpu, level);
+ if (ret < 0) {
+ return ret;
+ }
if (level >= KVM_PUT_RESET_STATE) {
ret = kvm_put_mp_state(x86_cpu);
if (ret < 0) {
@@ -2644,11 +2650,6 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
if (ret < 0) {
return ret;
}
-
- ret = kvm_put_vcpu_events(x86_cpu, level);
- if (ret < 0) {
- return ret;
- }
ret = kvm_put_debugregs(x86_cpu);
if (ret < 0) {
return ret;
@@ -2668,35 +2669,39 @@ int kvm_arch_get_registers(CPUState *cs)
assert(cpu_is_stopped(cs) || qemu_cpu_is_self(cs));
- ret = kvm_getput_regs(cpu, 0);
+ ret = kvm_get_vcpu_events(cpu);
if (ret < 0) {
goto out;
}
- ret = kvm_get_xsave(cpu);
+ /*
+ * KVM_GET_MPSTATE can modify CS and RIP, call it before
+ * KVM_GET_REGS and KVM_GET_SREGS.
+ */
+ ret = kvm_get_mp_state(cpu);
if (ret < 0) {
goto out;
}
- ret = kvm_get_xcrs(cpu);
+ ret = kvm_getput_regs(cpu, 0);
if (ret < 0) {
goto out;
}
- ret = kvm_get_sregs(cpu);
+ ret = kvm_get_xsave(cpu);
if (ret < 0) {
goto out;
}
- ret = kvm_get_msrs(cpu);
+ ret = kvm_get_xcrs(cpu);
if (ret < 0) {
goto out;
}
- ret = kvm_get_mp_state(cpu);
+ ret = kvm_get_sregs(cpu);
if (ret < 0) {
goto out;
}
- ret = kvm_get_apic(cpu);
+ ret = kvm_get_msrs(cpu);
if (ret < 0) {
goto out;
}
- ret = kvm_get_vcpu_events(cpu);
+ ret = kvm_get_apic(cpu);
if (ret < 0) {
goto out;
}
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index 4cda540..a860a31 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -418,6 +418,7 @@ new_state = "1"
def tearDown(self):
self.vm.shutdown()
os.remove(test_img)
+ os.remove(target_img)
os.remove(backing_img)
os.remove(self.blkdebug_file)
@@ -568,6 +569,7 @@ new_state = "1"
def tearDown(self):
self.vm.shutdown()
os.remove(test_img)
+ os.remove(target_img)
os.remove(backing_img)
os.remove(self.blkdebug_file)
@@ -821,7 +823,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
def tearDown(self):
self.vm.shutdown()
- for i in self.IMAGES + [ quorum_repair_img ]:
+ for i in self.IMAGES + [ quorum_repair_img, quorum_snapshot_file ]:
# Do a try/except because the test may have deleted some images
try:
os.remove(i)
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 6655aaf..a1c34ee 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -29,7 +29,8 @@ status=1 # failure is the default!
_cleanup()
{
- _cleanup_test_img
+ _cleanup_test_img
+ rm -f "$TEST_IMG.qcow2"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -72,15 +73,18 @@ echo
echo "=== Testing monolithicFlat creation and opening ==="
IMGOPTS="subformat=monolithicFlat" _make_test_img 2G
_img_info
+_cleanup_test_img
echo
echo "=== Testing monolithicFlat with zeroed_grain ==="
IMGOPTS="subformat=monolithicFlat,zeroed_grain=on" _make_test_img 2G
+_cleanup_test_img
echo
echo "=== Testing big twoGbMaxExtentFlat ==="
IMGOPTS="subformat=twoGbMaxExtentFlat" _make_test_img 1000G
$QEMU_IMG info $TEST_IMG | _filter_testdir | sed -e 's/cid: [0-9]*/cid: XXXXXXXX/'
+_cleanup_test_img
echo
echo "=== Testing malformed VMFS extent description line ==="
@@ -114,6 +118,7 @@ echo "=== Testing monolithicFlat with internally generated JSON file name ==="
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" 2>&1 \
| _filter_testdir | _filter_imgfmt
+_cleanup_test_img
echo
echo "=== Testing version 3 ==="
@@ -123,6 +128,7 @@ for i in {0..99}; do
$QEMU_IO -r -c "read -P $(( i % 10 + 0x30 )) $(( i * 64 * 1024 * 10 + i * 512 )) 512" $TEST_IMG \
| _filter_qemu_io
done
+_cleanup_test_img
echo
echo "=== Testing 4TB monolithicFlat creation and IO ==="
@@ -130,6 +136,7 @@ IMGOPTS="subformat=monolithicFlat" _make_test_img 4T
_img_info
$QEMU_IO -c "write -P 0xa 900G 512" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "read -v 900G 1024" "$TEST_IMG" | _filter_qemu_io
+_cleanup_test_img
echo
echo "=== Testing qemu-img map on extents ==="
@@ -139,12 +146,14 @@ for fmt in monolithicSparse twoGbMaxExtentSparse; do
$QEMU_IO -c "write 2147483136 1k" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "write 5G 1k" "$TEST_IMG" | _filter_qemu_io
$QEMU_IMG map "$TEST_IMG" | _filter_testdir
+ _cleanup_test_img
done
echo
echo "=== Testing afl image with a very large capacity ==="
_use_sample_img afl9.vmdk.bz2
_img_info
+_cleanup_test_img
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 6154509..f6dce79 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -2259,8 +2259,8 @@ read 512/512 bytes at offset 64931328
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
=== Testing 4TB monolithicFlat creation and IO ===
-Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat
-image: TEST_DIR/iotest-version3.IMGFMT
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat
+image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 4.0T (4398046511104 bytes)
wrote 512/512 bytes at offset 966367641600
@@ -2333,7 +2333,7 @@ read 1024/1024 bytes at offset 966367641600
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
=== Testing qemu-img map on extents ===
-Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=33285996544 subformat=monolithicSparse
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=monolithicSparse
wrote 1024/1024 bytes at offset 65024
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1024/1024 bytes at offset 2147483136
@@ -2341,10 +2341,10 @@ wrote 1024/1024 bytes at offset 2147483136
wrote 1024/1024 bytes at offset 5368709120
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Offset Length Mapped to File
-0 0x20000 0x3f0000 TEST_DIR/iotest-version3.vmdk
-0x7fff0000 0x20000 0x410000 TEST_DIR/iotest-version3.vmdk
-0x140000000 0x10000 0x430000 TEST_DIR/iotest-version3.vmdk
-Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=33285996544 subformat=twoGbMaxExtentSparse
+0 0x20000 0x3f0000 TEST_DIR/t.vmdk
+0x7fff0000 0x20000 0x410000 TEST_DIR/t.vmdk
+0x140000000 0x10000 0x430000 TEST_DIR/t.vmdk
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=twoGbMaxExtentSparse
wrote 1024/1024 bytes at offset 65024
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1024/1024 bytes at offset 2147483136
@@ -2352,10 +2352,10 @@ wrote 1024/1024 bytes at offset 2147483136
wrote 1024/1024 bytes at offset 5368709120
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Offset Length Mapped to File
-0 0x20000 0x50000 TEST_DIR/iotest-version3-s001.vmdk
-0x7fff0000 0x10000 0x70000 TEST_DIR/iotest-version3-s001.vmdk
-0x80000000 0x10000 0x50000 TEST_DIR/iotest-version3-s002.vmdk
-0x140000000 0x10000 0x50000 TEST_DIR/iotest-version3-s003.vmdk
+0 0x20000 0x50000 TEST_DIR/t-s001.vmdk
+0x7fff0000 0x10000 0x70000 TEST_DIR/t-s001.vmdk
+0x80000000 0x10000 0x50000 TEST_DIR/t-s002.vmdk
+0x140000000 0x10000 0x50000 TEST_DIR/t-s003.vmdk
=== Testing afl image with a very large capacity ===
qemu-img: Can't get image size 'TEST_DIR/afl9.IMGFMT': File too large
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
index 352e78c..e4f6ea9 100755
--- a/tests/qemu-iotests/063
+++ b/tests/qemu-iotests/063
@@ -31,7 +31,7 @@ status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
- rm -f "$TEST_IMG.orig" "$TEST_IMG.raw" "$TEST_IMG.raw2"
+ rm -f "$TEST_IMG.orig" "$TEST_IMG.raw1" "$TEST_IMG.raw2"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -91,8 +91,6 @@ if $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG.orig" "$TEST_IMG" >/dev
exit 1
fi
-rm -f "$TEST_IMG.orig" "$TEST_IMG.raw" "$TEST_IMG.raw2"
-
echo "*** done"
rm -f $seq.full
status=0
diff --git a/tests/qemu-iotests/074 b/tests/qemu-iotests/074
index aba126c..b17866b 100755
--- a/tests/qemu-iotests/074
+++ b/tests/qemu-iotests/074
@@ -32,6 +32,7 @@ _cleanup()
echo "Cleanup"
_cleanup_test_img
rm "${TEST_IMG2}"
+ rm -f "$TEST_DIR/blkdebug.conf"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index d0d2c2b..8e76e62 100644
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -336,7 +336,12 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
(('0xab', 0, 512),
('0xfe', '16M', '256k'),
('0x64', '32736k', '64k')))
-
+ # Check the dirty bitmap stats
+ result = self.vm.qmp('query-block')
+ self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/name', 'bitmap0')
+ self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/count', 458752)
+ self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/granularity', 65536)
+ self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/status', 'active')
# Prepare a cluster_size=128k backup target without a backing file.
(target, _) = bitmap0.new_target()
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
index 40a3405..2f9d7b9 100755
--- a/tests/qemu-iotests/141
+++ b/tests/qemu-iotests/141
@@ -31,7 +31,7 @@ _cleanup()
{
_cleanup_qemu
_cleanup_test_img
- rm -f "$TEST_DIR/{b,m,o}.$IMGFMT"
+ rm -f "$TEST_DIR"/{b,m,o}.$IMGFMT
}
trap "_cleanup; exit \$status" 0 1 2 3 15
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
index 0b45d78..fa25eb2 100755
--- a/tests/qemu-iotests/153
+++ b/tests/qemu-iotests/153
@@ -35,6 +35,7 @@ _cleanup()
rm -f "${TEST_IMG}.convert"
rm -f "${TEST_IMG}.a"
rm -f "${TEST_IMG}.b"
+ rm -f "${TEST_IMG}.c"
rm -f "${TEST_IMG}.lnk"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
index 2c4a06e..e75dc4d 100755
--- a/tests/qemu-iotests/156
+++ b/tests/qemu-iotests/156
@@ -38,7 +38,7 @@ status=1 # failure is the default!
_cleanup()
{
_cleanup_qemu
- rm -f "$TEST_IMG{,.target}{,.backing,.overlay}"
+ rm -f "$TEST_IMG"{,.target}{,.backing,.overlay}
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -83,7 +83,7 @@ _send_qemu_cmd $QEMU_HANDLE \
'return'
# Create target image
-TEST_IMG="$TEST_IMG.target.overlay" _make_test_img -b "$TEST_IMG.target" 1M
+TEST_IMG="$TEST_IMG.target.overlay" _make_test_img -u -b "$TEST_IMG.target" 1M
# Mirror snapshot
_send_qemu_cmd $QEMU_HANDLE \
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
index cad2bd7..477a806 100755
--- a/tests/qemu-iotests/162
+++ b/tests/qemu-iotests/162
@@ -28,6 +28,13 @@ echo "QA output created by $seq"
here="$PWD"
status=1 # failure is the default!
+_cleanup()
+{
+ rm -f "${TEST_DIR}/qemu-nbd.pid"
+ rm -f 42
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
diff --git a/tests/qemu-iotests/179 b/tests/qemu-iotests/179
index 7bc8db8..115944a 100755
--- a/tests/qemu-iotests/179
+++ b/tests/qemu-iotests/179
@@ -30,6 +30,7 @@ status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
+ rm -f "$TEST_DIR/blkdebug.conf"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
index ab83ee4..2b9f618 100755
--- a/tests/qemu-iotests/186
+++ b/tests/qemu-iotests/186
@@ -56,7 +56,7 @@ function do_run_qemu()
done
fi
echo quit
- ) | $QEMU -S -nodefaults -display none -device virtio-scsi-pci -monitor stdio "$@"
+ ) | $QEMU -S -nodefaults -display none -device virtio-scsi-pci -monitor stdio "$@" 2>&1
echo
}
diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
index b8bf9a2..c8377fe 100644
--- a/tests/qemu-iotests/186.out
+++ b/tests/qemu-iotests/186.out
@@ -442,28 +442,28 @@ ide0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
Cache mode: writeback
(qemu) quit
-qemu-system-x86_64: -drive if=scsi,driver=null-co: warning: bus=0,unit=0 is deprecated with this machine type
Testing: -drive if=scsi,driver=null-co
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) info block
+(qemu) QEMU_PROG: -drive if=scsi,driver=null-co: warning: bus=0,unit=0 is deprecated with this machine type
+info block
scsi0-hd0 (NODE_NAME): null-co:// (null-co)
Attached to: /machine/unattached/device[27]/scsi.0/legacy[0]
Cache mode: writeback
(qemu) quit
-qemu-system-x86_64: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
Testing: -drive if=scsi,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) info block
+(qemu) QEMU_PROG: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
+info block
scsi0-cd0: [not inserted]
Attached to: /machine/unattached/device[27]/scsi.0/legacy[0]
Removable device: not locked, tray closed
(qemu) quit
-qemu-system-x86_64: -drive if=scsi,driver=null-co,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
Testing: -drive if=scsi,driver=null-co,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) info block
+(qemu) QEMU_PROG: -drive if=scsi,driver=null-co,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
+info block
scsi0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
Attached to: /machine/unattached/device[27]/scsi.0/legacy[0]
Removable device: not locked, tray closed
diff --git a/tests/qemu-iotests/190 b/tests/qemu-iotests/190
new file mode 100755
index 0000000..8f808fe
--- /dev/null
+++ b/tests/qemu-iotests/190
@@ -0,0 +1,59 @@
+#!/bin/bash
+#
+# qemu-img measure sub-command tests on huge qcow2 files
+#
+# Copyright (C) 2017 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=eblake@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+ rm -f "$TEST_IMG.converted"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+# See 178 for more extensive tests across more formats
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+echo "== Huge file =="
+echo
+
+IMGOPTS='cluster_size=2M' _make_test_img 2T
+
+$QEMU_IMG measure -O raw -f qcow2 "$TEST_IMG"
+$QEMU_IMG measure -O qcow2 -o cluster_size=64k -f qcow2 "$TEST_IMG"
+$QEMU_IMG measure -O qcow2 -o cluster_size=2M -f qcow2 "$TEST_IMG"
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/190.out b/tests/qemu-iotests/190.out
new file mode 100644
index 0000000..d001942
--- /dev/null
+++ b/tests/qemu-iotests/190.out
@@ -0,0 +1,11 @@
+QA output created by 190
+== Huge file ==
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2199023255552
+required size: 2199023255552
+fully allocated size: 2199023255552
+required size: 335806464
+fully allocated size: 2199359062016
+required size: 18874368
+fully allocated size: 2199042129920
+*** done
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 2548e58..bfbc80e 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -92,6 +92,7 @@ else
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
fi
fi
+ORIG_TEST_IMG="$TEST_IMG"
_optstr_add()
{
@@ -228,6 +229,8 @@ _cleanup_test_img()
if [ -n "$SAMPLE_IMG_FILE" ]
then
rm -f "$TEST_DIR/$SAMPLE_IMG_FILE"
+ SAMPLE_IMG_FILE=
+ TEST_IMG="$ORIG_TEST_IMG"
fi
;;
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 287f0ea..8238110 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -184,3 +184,4 @@
186 rw auto
188 rw auto quick
189 rw auto
+190 rw auto quick
diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index e78f701..d7a96cb 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -17,6 +17,8 @@
#include "qemu/timer.h"
#include "hw/timer/mc146818rtc_regs.h"
+#define UIP_HOLD_LENGTH (8 * NANOSECONDS_PER_SECOND / 32768)
+
static uint8_t base = 0x70;
static int bcd2dec(int value)
@@ -297,15 +299,53 @@ static void alarm_time(void)
g_assert(cmos_read(RTC_REG_C) == 0);
}
+static void set_time_regs(int h, int m, int s)
+{
+ cmos_write(RTC_HOURS, h);
+ cmos_write(RTC_MINUTES, m);
+ cmos_write(RTC_SECONDS, s);
+}
+
static void set_time(int mode, int h, int m, int s)
{
- /* set BCD 12 hour mode */
cmos_write(RTC_REG_B, mode);
-
cmos_write(RTC_REG_A, 0x76);
+ set_time_regs(h, m, s);
+ cmos_write(RTC_REG_A, 0x26);
+}
+
+static void set_datetime_bcd(int h, int min, int s, int d, int m, int y)
+{
cmos_write(RTC_HOURS, h);
- cmos_write(RTC_MINUTES, m);
+ cmos_write(RTC_MINUTES, min);
+ cmos_write(RTC_SECONDS, s);
+ cmos_write(RTC_YEAR, y & 0xFF);
+ cmos_write(RTC_CENTURY, y >> 8);
+ cmos_write(RTC_MONTH, m);
+ cmos_write(RTC_DAY_OF_MONTH, d);
+}
+
+static void set_datetime_dec(int h, int min, int s, int d, int m, int y)
+{
+ cmos_write(RTC_HOURS, h);
+ cmos_write(RTC_MINUTES, min);
cmos_write(RTC_SECONDS, s);
+ cmos_write(RTC_YEAR, y % 100);
+ cmos_write(RTC_CENTURY, y / 100);
+ cmos_write(RTC_MONTH, m);
+ cmos_write(RTC_DAY_OF_MONTH, d);
+}
+
+static void set_datetime(int mode, int h, int min, int s, int d, int m, int y)
+{
+ cmos_write(RTC_REG_B, mode);
+
+ cmos_write(RTC_REG_A, 0x76);
+ if (mode & REG_B_DM) {
+ set_datetime_dec(h, min, s, d, m, y);
+ } else {
+ set_datetime_bcd(h, min, s, d, m, y);
+ }
cmos_write(RTC_REG_A, 0x26);
}
@@ -316,6 +356,17 @@ static void set_time(int mode, int h, int m, int s)
g_assert_cmpint(cmos_read(RTC_SECONDS), ==, s); \
} while(0)
+#define assert_datetime_bcd(h, min, s, d, m, y) \
+ do { \
+ g_assert_cmpint(cmos_read(RTC_HOURS), ==, h); \
+ g_assert_cmpint(cmos_read(RTC_MINUTES), ==, min); \
+ g_assert_cmpint(cmos_read(RTC_SECONDS), ==, s); \
+ g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, d); \
+ g_assert_cmpint(cmos_read(RTC_MONTH), ==, m); \
+ g_assert_cmpint(cmos_read(RTC_YEAR), ==, (y & 0xFF)); \
+ g_assert_cmpint(cmos_read(RTC_CENTURY), ==, (y >> 8)); \
+ } while(0)
+
static void basic_12h_bcd(void)
{
/* set BCD 12 hour mode */
@@ -506,41 +557,84 @@ static void fuzz_registers(void)
static void register_b_set_flag(void)
{
+ if (cmos_read(RTC_REG_A) & REG_A_UIP) {
+ clock_step(UIP_HOLD_LENGTH + NANOSECONDS_PER_SECOND / 5);
+ }
+ g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0);
+
/* Enable binary-coded decimal (BCD) mode and SET flag in Register B*/
cmos_write(RTC_REG_B, REG_B_24H | REG_B_SET);
- cmos_write(RTC_REG_A, 0x76);
- cmos_write(RTC_YEAR, 0x11);
- cmos_write(RTC_CENTURY, 0x20);
- cmos_write(RTC_MONTH, 0x02);
- cmos_write(RTC_DAY_OF_MONTH, 0x02);
- cmos_write(RTC_HOURS, 0x02);
- cmos_write(RTC_MINUTES, 0x04);
- cmos_write(RTC_SECONDS, 0x58);
- cmos_write(RTC_REG_A, 0x26);
+ set_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
- /* Since SET flag is still enabled, these are equality checks. */
- g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
- g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
- g_assert_cmpint(cmos_read(RTC_SECONDS), ==, 0x58);
- g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
- g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
- g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
- g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
+ assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
+
+ /* Since SET flag is still enabled, time does not advance. */
+ clock_step(1000000000LL);
+ assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
/* Disable SET flag in Register B */
cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_SET);
- g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
- g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
+ assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
- /* Since SET flag is disabled, this is an inequality check.
- * We (reasonably) assume that no (sexagesimal) overflow occurs. */
- g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
- g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
- g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
- g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
- g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
+ /* Since SET flag is disabled, the clock now advances. */
+ clock_step(1000000000LL);
+ assert_datetime_bcd(0x02, 0x04, 0x59, 0x02, 0x02, 0x2011);
+}
+
+static void divider_reset(void)
+{
+ /* Enable binary-coded decimal (BCD) mode in Register B*/
+ cmos_write(RTC_REG_B, REG_B_24H);
+
+ /* Enter divider reset */
+ cmos_write(RTC_REG_A, 0x76);
+ set_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
+
+ assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
+
+ /* Since divider reset flag is still enabled, these are equality checks. */
+ clock_step(1000000000LL);
+ assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
+
+ /* The first update ends 500 ms after divider reset */
+ cmos_write(RTC_REG_A, 0x26);
+ clock_step(500000000LL - UIP_HOLD_LENGTH - 1);
+ g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0);
+ assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
+
+ clock_step(1);
+ g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, !=, 0);
+ clock_step(UIP_HOLD_LENGTH);
+ g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0);
+
+ assert_datetime_bcd(0x02, 0x04, 0x59, 0x02, 0x02, 0x2011);
+}
+
+static void uip_stuck(void)
+{
+ set_datetime(REG_B_24H, 0x02, 0x04, 0x58, 0x02, 0x02, 0x2011);
+
+ /* The first update ends 500 ms after divider reset */
+ (void)cmos_read(RTC_REG_C);
+ clock_step(500000000LL);
+ g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0);
+ assert_datetime_bcd(0x02, 0x04, 0x59, 0x02, 0x02, 0x2011);
+
+ /* UF is now set. */
+ cmos_write(RTC_HOURS_ALARM, 0x02);
+ cmos_write(RTC_MINUTES_ALARM, 0xC0);
+ cmos_write(RTC_SECONDS_ALARM, 0xC0);
+
+ /* Because the alarm will fire soon, reading register A will latch UIP. */
+ clock_step(1000000000LL - UIP_HOLD_LENGTH / 2);
+ g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, !=, 0);
+
+ /* Move the alarm far away. This must not cause UIP to remain stuck! */
+ cmos_write(RTC_HOURS_ALARM, 0x03);
+ clock_step(UIP_HOLD_LENGTH);
+ g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0);
}
#define RTC_PERIOD_CODE1 13 /* 8 Hz */
@@ -609,7 +703,9 @@ int main(int argc, char **argv)
qtest_add_func("/rtc/basic/bcd-12h", basic_12h_bcd);
qtest_add_func("/rtc/set-year/20xx", set_year_20xx);
qtest_add_func("/rtc/set-year/1980", set_year_1980);
- qtest_add_func("/rtc/misc/register_b_set_flag", register_b_set_flag);
+ qtest_add_func("/rtc/update/register_b_set_flag", register_b_set_flag);
+ qtest_add_func("/rtc/update/divider-reset", divider_reset);
+ qtest_add_func("/rtc/update/uip-stuck", uip_stuck);
qtest_add_func("/rtc/misc/fuzz-registers", fuzz_registers);
qtest_add_func("/rtc/periodic/interrupt", periodic_timer);
diff --git a/vl.c b/vl.c
index fb6b2ef..99fcfa0 100644
--- a/vl.c
+++ b/vl.c
@@ -2344,10 +2344,12 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
Error *local_err = NULL;
- qemu_chr_new_from_opts(opts, &local_err);
- if (local_err) {
- error_report_err(local_err);
- return -1;
+ if (!qemu_chr_new_from_opts(opts, &local_err)) {
+ if (local_err) {
+ error_report_err(local_err);
+ return -1;
+ }
+ exit(0);
}
return 0;
}
@@ -4787,8 +4789,8 @@ int main(int argc, char **argv, char **envp)
replay_disable_events();
iothread_stop_all();
- bdrv_close_all();
pause_all_vcpus();
+ bdrv_close_all();
res_free();
/* vhost-user must be cleaned up before chardevs. */