* Xen fix (Anthony)

* chardev fixes (Anton, Marc-André)
 * small dead code removal (Zhongyi)
 * documentation (Dan)
 * bugfixes (David)
 * decrease migration downtime (Jay)
 * improved error output (Laurent)
 * RTC tests and bugfix (me)
 * Bluetooth clang analyzer fix (me)
 * KVM CPU hotplug race (Peng Hao)
 * Two other patches from Philippe's clang analyzer series
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJZgKSlAAoJEL/70l94x66DTZ0IAKtZ3ASQiVaniYey4DNwq38G
 6ivVfOy9ZHvWozN4pVf+CC8o7nGTGcm2zT5wUDs/7OvjZM9Mit7fmLb28DbGjgPk
 dFNiuA1VSR+7lQ90NNx5iypU760zJfLlmI34YsrrK7msQy7KI7m4QAr1DHhitLN8
 LKaq3/Zhb4kB5i/GxcLF+ozh4BZ3v3kJ2KiqQYWxGhWhODnn+ejzWx+Zp+vAK7Nl
 QoMHKHYt9BlsTDg3zMpMwEfdocy7etXcRllC+jaeNjvboQiiyidUH1PKGOKt3YdL
 j8aAxZ9rdLvEP9zA572Hh56869FZiljYkhohcKDHx6KrRyWQeoG80GCLgDq+cUs=
 =4Rey
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* Xen fix (Anthony)
* chardev fixes (Anton, Marc-André)
* small dead code removal (Zhongyi)
* documentation (Dan)
* bugfixes (David)
* decrease migration downtime (Jay)
* improved error output (Laurent)
* RTC tests and bugfix (me)
* Bluetooth clang analyzer fix (me)
* KVM CPU hotplug race (Peng Hao)
* Two other patches from Philippe's clang analyzer series

# gpg: Signature made Tue 01 Aug 2017 16:56:21 BST
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  mc146818rtc: implement UIP latching as intended
  mc146818rtc: simplify check_update_timer
  rtc-test: introduce more update tests
  rtc-test: cleanup register_b_set_flag test
  hw/scsi/vmw_pvscsi: Convert to realize
  hw/scsi/vmw_pvscsi: Remove the dead error handling
  migration: optimize the downtime
  qemu-options: document existance of versioned machine types
  bt: stop the sdp memory allocation craziness
  exec: Add lock parameter to qemu_ram_ptr_length
  target-i386: kvm_get/put_vcpu_events don't handle sipi_vector
  docs: document deprecation policy & deprecated features in appendix
  char: don't exit on hmp 'chardev-add help'
  char-fd: remove useless chr pointer
  accel: cleanup error output
  cpu_physical_memory_sync_dirty_bitmap: Fix alignment check
  vl.c/exit: pause cpus before closing block devices

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-08-01 18:03:04 +01:00
commit 82d3d409b8
16 changed files with 440 additions and 109 deletions

View File

@ -33,6 +33,7 @@
#include "sysemu/qtest.h"
#include "hw/xen/xen.h"
#include "qom/object.h"
#include "qemu/error-report.h"
static const TypeInfo accel_type = {
.name = TYPE_ACCEL,
@ -69,19 +70,20 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
void configure_accelerator(MachineState *ms)
{
const char *p;
const char *accel, *p;
char buf[10];
int ret;
bool accel_initialised = false;
bool init_failed = false;
AccelClass *acc = NULL;
p = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (p == NULL) {
accel = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (accel == NULL) {
/* Use the default "accelerator", tcg */
p = "tcg";
accel = "tcg";
}
p = accel;
while (!accel_initialised && *p != '\0') {
if (*p == ':') {
p++;
@ -89,7 +91,6 @@ void configure_accelerator(MachineState *ms)
p = get_opt_name(buf, sizeof(buf), p, ':');
acc = accel_find(buf);
if (!acc) {
fprintf(stderr, "\"%s\" accelerator not found.\n", buf);
continue;
}
if (acc->available && !acc->available()) {
@ -100,9 +101,8 @@ void configure_accelerator(MachineState *ms)
ret = accel_init_machine(acc, ms);
if (ret < 0) {
init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n",
acc->name,
strerror(-ret));
error_report("failed to initialize %s: %s",
acc->name, strerror(-ret));
} else {
accel_initialised = true;
}
@ -110,13 +110,13 @@ void configure_accelerator(MachineState *ms)
if (!accel_initialised) {
if (!init_failed) {
fprintf(stderr, "No accelerator found!\n");
error_report("-machine accel=%s: No accelerator found", accel);
}
exit(1);
}
if (init_failed) {
fprintf(stderr, "Back to %s accelerator.\n", acc->name);
error_report("Back to %s accelerator", acc->name);
}
}

View File

@ -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)

View File

@ -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) {

12
exec.c
View File

@ -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;

View File

@ -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),

View File

@ -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;

View File

@ -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:
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 = s->cmos_data[s->cmos_index];
if (update_in_progress(s)) {
ret |= REG_A_UIP;
}
break;
case RTC_REG_C:
ret = s->cmos_data[s->cmos_index];

View File

@ -29,7 +29,7 @@
typedef struct FDChardev {
Chardev parent;
Chardev *chr;
QIOChannel *ioc_in, *ioc_out;
int max_size;
} FDChardev;

View File

@ -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);

View File

@ -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();

View File

@ -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)
{

View File

@ -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

View File

@ -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,

View File

@ -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,6 +2669,18 @@ int kvm_arch_get_registers(CPUState *cs)
assert(cpu_is_stopped(cs) || qemu_cpu_is_self(cs));
ret = kvm_get_vcpu_events(cpu);
if (ret < 0) {
goto out;
}
/*
* 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_getput_regs(cpu, 0);
if (ret < 0) {
goto out;
@ -2688,18 +2701,10 @@ int kvm_arch_get_registers(CPUState *cs)
if (ret < 0) {
goto out;
}
ret = kvm_get_mp_state(cpu);
if (ret < 0) {
goto out;
}
ret = kvm_get_apic(cpu);
if (ret < 0) {
goto out;
}
ret = kvm_get_vcpu_events(cpu);
if (ret < 0) {
goto out;
}
ret = kvm_get_debugregs(cpu);
if (ret < 0) {
goto out;

View File

@ -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(int mode, int h, int m, int s)
static void set_time_regs(int h, int m, int s)
{
/* set BCD 12 hour mode */
cmos_write(RTC_REG_B, mode);
cmos_write(RTC_REG_A, 0x76);
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)
{
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, 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);

6
vl.c
View File

@ -2344,11 +2344,13 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
Error *local_err = NULL;
qemu_chr_new_from_opts(opts, &local_err);
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. */