aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure24
-rw-r--r--hw/usb/hcd-ehci.c7
-rw-r--r--hw/usb/hcd-ehci.h1
-rw-r--r--hw/usb/hcd-xhci.c6
-rw-r--r--include/migration/colo.h3
-rw-r--r--include/migration/misc.h2
-rw-r--r--include/migration/register.h3
-rw-r--r--include/migration/vmstate.h1
-rw-r--r--include/qemu/typedefs.h2
-rw-r--r--include/ui/spice-display.h2
-rw-r--r--migration/block.c6
-rw-r--r--migration/colo-failover.c2
-rw-r--r--migration/colo.c4
-rw-r--r--migration/exec.c2
-rw-r--r--migration/fd.c2
-rw-r--r--migration/global_state.c1
-rw-r--r--migration/migration.c31
-rw-r--r--migration/migration.h2
-rw-r--r--migration/postcopy-ram.c2
-rw-r--r--migration/qemu-file.c2
-rw-r--r--migration/ram.c24
-rw-r--r--migration/savevm.c25
-rw-r--r--migration/savevm.h3
-rw-r--r--target/s390x/cpu.h9
-rw-r--r--target/s390x/cpu_models.c8
-rw-r--r--target/s390x/helper.c44
-rw-r--r--target/s390x/insn-data.def2
-rw-r--r--target/s390x/misc_helper.c31
-rw-r--r--target/s390x/mmu_helper.c6
-rw-r--r--target/s390x/translate.c12
-rw-r--r--ui/cocoa.m60
-rw-r--r--ui/spice-core.c1
-rw-r--r--ui/spice-display.c3
-rw-r--r--ui/spice-input.c2
34 files changed, 199 insertions, 136 deletions
diff --git a/configure b/configure
index b147191..db0798d 100755
--- a/configure
+++ b/configure
@@ -2301,14 +2301,14 @@ fi
# GTK probe
if test "$gtkabi" = ""; then
- # The GTK ABI was not specified explicitly, so try whether 2.0 is available.
- # Use 3.0 as a fallback if that is available.
- if $pkg_config --exists "gtk+-2.0 >= 2.18.0"; then
- gtkabi=2.0
- elif $pkg_config --exists "gtk+-3.0 >= 3.0.0"; then
+ # The GTK ABI was not specified explicitly, so try whether 3.0 is available.
+ # Use 2.0 as a fallback if that is available.
+ if $pkg_config --exists "gtk+-3.0 >= 3.0.0"; then
gtkabi=3.0
- else
+ elif $pkg_config --exists "gtk+-2.0 >= 2.18.0"; then
gtkabi=2.0
+ else
+ gtkabi=3.0
fi
fi
@@ -2331,7 +2331,7 @@ if test "$gtk" != "no"; then
libs_softmmu="$gtk_libs $libs_softmmu"
gtk="yes"
elif test "$gtk" = "yes"; then
- feature_not_found "gtk" "Install gtk2 or gtk3 devel"
+ feature_not_found "gtk" "Install gtk3-devel"
else
gtk="no"
fi
@@ -2598,12 +2598,12 @@ fi
# sdl-config even without cross prefix, and favour pkg-config over sdl-config.
if test "$sdlabi" = ""; then
- if $pkg_config --exists "sdl"; then
- sdlabi=1.2
- elif $pkg_config --exists "sdl2"; then
+ if $pkg_config --exists "sdl2"; then
sdlabi=2.0
- else
+ elif $pkg_config --exists "sdl"; then
sdlabi=1.2
+ else
+ sdlabi=2.0
fi
fi
@@ -2630,7 +2630,7 @@ elif has ${sdl_config}; then
sdlversion=$($sdlconfig --version)
else
if test "$sdl" = "yes" ; then
- feature_not_found "sdl" "Install SDL devel"
+ feature_not_found "sdl" "Install SDL2-devel"
fi
sdl=no
fi
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 17c572c..73090e0 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2241,6 +2241,11 @@ static void ehci_work_bh(void *opaque)
uint64_t uframes, skipped_uframes;
int i;
+ if (ehci->working) {
+ return;
+ }
+ ehci->working = true;
+
t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ns_elapsed = t_now - ehci->last_run_ns;
uframes = ns_elapsed / UFRAME_TIMER_NS;
@@ -2322,6 +2327,8 @@ static void ehci_work_bh(void *opaque)
}
timer_mod(ehci->frame_timer, expire_time);
}
+
+ ehci->working = false;
}
static void ehci_work_timer(void *opaque)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 938d8aa..821f1de 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -297,6 +297,7 @@ struct EHCIState {
*/
QEMUTimer *frame_timer;
QEMUBH *async_bh;
+ bool working;
uint32_t astate; /* Current state in asynchronous schedule */
uint32_t pstate; /* Current state in periodic schedule */
USBPort ports[NB_PORTS];
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index a0c7960..760135c 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1912,6 +1912,8 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
}
assert(!xfer->running_retry);
if (xfer->complete) {
+ /* update ring dequeue ptr */
+ xhci_set_ep_state(xhci, epctx, stctx, epctx->state);
xhci_ep_free_xfer(epctx->retry);
}
epctx->retry = NULL;
@@ -1962,6 +1964,8 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
xhci_fire_transfer(xhci, xfer, epctx);
}
if (xfer->complete) {
+ /* update ring dequeue ptr */
+ xhci_set_ep_state(xhci, epctx, stctx, epctx->state);
xhci_ep_free_xfer(xfer);
xfer = NULL;
}
@@ -1979,8 +1983,6 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
break;
}
}
- /* update ring dequeue ptr */
- xhci_set_ep_state(xhci, epctx, stctx, epctx->state);
epctx->kick_active--;
ep = xhci_epid_to_usbep(epctx);
diff --git a/include/migration/colo.h b/include/migration/colo.h
index ba0bb6e..be6beba 100644
--- a/include/migration/colo.h
+++ b/include/migration/colo.h
@@ -14,9 +14,6 @@
#define QEMU_COLO_H
#include "qemu-common.h"
-#include "qemu/coroutine_int.h"
-#include "qemu/thread.h"
-#include "qemu/main-loop.h"
bool colo_supported(void);
void colo_info_init(void);
diff --git a/include/migration/misc.h b/include/migration/misc.h
index d5a433a..65c7070 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -14,6 +14,8 @@
#ifndef MIGRATION_MISC_H
#define MIGRATION_MISC_H
+#include "qemu/notify.h"
+
/* migration/ram.c */
void ram_mig_init(void);
diff --git a/include/migration/register.h b/include/migration/register.h
index 717c617..d9498d9 100644
--- a/include/migration/register.h
+++ b/include/migration/register.h
@@ -14,9 +14,6 @@
#ifndef MIGRATION_REGISTER_H
#define MIGRATION_REGISTER_H
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
typedef struct SaveVMHandlers {
/* This runs inside the iothread lock. */
SaveStateHandler *save_state;
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index f3f3c2a..e85fbd8 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -29,7 +29,6 @@
#include "migration/qjson.h"
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
typedef struct VMStateInfo VMStateInfo;
typedef struct VMStateDescription VMStateDescription;
typedef struct VMStateField VMStateField;
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 51958bf..f745d5f 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -96,5 +96,7 @@ typedef struct uWireSlave uWireSlave;
typedef struct VirtIODevice VirtIODevice;
typedef struct Visitor Visitor;
typedef struct node_info NodeInfo;
+typedef void SaveStateHandler(QEMUFile *f, void *opaque);
+typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
#endif /* QEMU_TYPEDEFS_H */
diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index 184d4c3..4ba9444 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -140,6 +140,8 @@ struct SimpleSpiceCursor {
QXLCursor cursor;
};
+extern bool spice_opengl;
+
int qemu_spice_rect_is_empty(const QXLRect* r);
void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
diff --git a/migration/block.c b/migration/block.c
index ae06975..3aae5a3 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -15,19 +15,13 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qemu-common.h"
-#include "block/block.h"
#include "qemu/error-report.h"
-#include "qemu/main-loop.h"
-#include "hw/hw.h"
#include "qemu/cutils.h"
#include "qemu/queue.h"
-#include "qemu/timer.h"
#include "block.h"
#include "migration/misc.h"
#include "migration.h"
#include "migration/register.h"
-#include "sysemu/blockdev.h"
#include "qemu-file.h"
#include "migration/vmstate.h"
#include "sysemu/block-backend.h"
diff --git a/migration/colo-failover.c b/migration/colo-failover.c
index cc229f5..f991486 100644
--- a/migration/colo-failover.c
+++ b/migration/colo-failover.c
@@ -13,6 +13,8 @@
#include "qemu/osdep.h"
#include "migration/colo.h"
#include "migration/failover.h"
+#include "qemu/main-loop.h"
+#include "migration.h"
#include "qmp-commands.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
diff --git a/migration/colo.c b/migration/colo.c
index 45e9b46..c4ba4c3 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -11,7 +11,6 @@
*/
#include "qemu/osdep.h"
-#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "qemu-file-channel.h"
#include "migration.h"
@@ -22,7 +21,6 @@
#include "io/channel-buffer.h"
#include "trace.h"
#include "qemu/error-report.h"
-#include "qapi/error.h"
#include "migration/failover.h"
#include "replication.h"
#include "qmp-commands.h"
@@ -354,7 +352,7 @@ static int colo_do_checkpoint_transaction(MigrationState *s,
qemu_savevm_state_header(fb);
qemu_savevm_state_begin(fb);
qemu_mutex_lock_iothread();
- qemu_savevm_state_complete_precopy(fb, false);
+ qemu_savevm_state_complete_precopy(fb, false, false);
qemu_mutex_unlock_iothread();
qemu_fflush(fb);
diff --git a/migration/exec.c b/migration/exec.c
index b1de445..08b599e 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -19,10 +19,8 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qemu-common.h"
#include "channel.h"
#include "exec.h"
-#include "migration.h"
#include "io/channel-command.h"
#include "trace.h"
diff --git a/migration/fd.c b/migration/fd.c
index b2384bf..30f5258 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -16,10 +16,8 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qemu-common.h"
#include "channel.h"
#include "fd.h"
-#include "migration.h"
#include "monitor/monitor.h"
#include "io/channel-util.h"
#include "trace.h"
diff --git a/migration/global_state.c b/migration/global_state.c
index 16ac63f..f792cf5 100644
--- a/migration/global_state.c
+++ b/migration/global_state.c
@@ -17,7 +17,6 @@
#include "qapi/util.h"
#include "migration/global_state.h"
#include "migration/vmstate.h"
-#include "sysemu/sysemu.h"
#include "trace.h"
typedef struct {
diff --git a/migration/migration.c b/migration/migration.c
index 8ef6d6c..f588329 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -16,7 +16,6 @@
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
-#include "qemu/main-loop.h"
#include "migration/blocker.h"
#include "exec.h"
#include "fd.h"
@@ -30,11 +29,9 @@
#include "qemu-file-channel.h"
#include "qemu-file.h"
#include "migration/vmstate.h"
-#include "sysemu/sysemu.h"
#include "block/block.h"
#include "qapi/qmp/qerror.h"
#include "qapi/util.h"
-#include "qemu/sockets.h"
#include "qemu/rcu.h"
#include "block.h"
#include "postcopy-ram.h"
@@ -42,9 +39,6 @@
#include "qmp-commands.h"
#include "trace.h"
#include "qapi-event.h"
-#include "qom/cpu.h"
-#include "exec/memory.h"
-#include "exec/address-spaces.h"
#include "exec/target_page.h"
#include "io/channel-buffer.h"
#include "migration/colo.h"
@@ -1559,7 +1553,7 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
* Cause any non-postcopiable, but iterative devices to
* send out their final data.
*/
- qemu_savevm_state_complete_precopy(ms->to_dst_file, true);
+ qemu_savevm_state_complete_precopy(ms->to_dst_file, true, false);
/*
* in Finish migrate and with the io-lock held everything should
@@ -1603,7 +1597,7 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
*/
qemu_savevm_send_postcopy_listen(fb);
- qemu_savevm_state_complete_precopy(fb, false);
+ qemu_savevm_state_complete_precopy(fb, false, false);
qemu_savevm_send_ping(fb, 3);
qemu_savevm_send_postcopy_run(fb);
@@ -1701,20 +1695,15 @@ static void migration_completion(MigrationState *s, int current_active_state,
ret = global_state_store();
if (!ret) {
+ bool inactivate = !migrate_colo_enabled();
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
if (ret >= 0) {
qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
- qemu_savevm_state_complete_precopy(s->to_dst_file, false);
+ ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
+ inactivate);
}
- /*
- * Don't mark the image with BDRV_O_INACTIVE flag if
- * we will go into COLO stage later.
- */
- if (ret >= 0 && !migrate_colo_enabled()) {
- ret = bdrv_inactivate_all();
- if (ret >= 0) {
- s->block_inactive = true;
- }
+ if (inactivate && ret >= 0) {
+ s->block_inactive = true;
}
}
qemu_mutex_unlock_iothread();
@@ -1814,7 +1803,11 @@ static void *migration_thread(void *opaque)
qemu_savevm_state_header(s->to_dst_file);
- if (s->to_dst_file) {
+ /*
+ * If we opened the return path, we need to make sure dst has it
+ * opened as well.
+ */
+ if (s->rp_state.from_dst_file) {
/* Now tell the dest that it should open its end so it can reply */
qemu_savevm_send_open_return_path(s->to_dst_file);
diff --git a/migration/migration.h b/migration/migration.h
index 601e4ab..d9a268a 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -14,10 +14,8 @@
#ifndef QEMU_MIGRATION_H
#define QEMU_MIGRATION_H
-#include "qapi/qmp/qdict.h"
#include "qemu-common.h"
#include "qemu/thread.h"
-#include "qemu/notify.h"
#include "qapi-types.h"
#include "exec/cpu-common.h"
#include "qemu/coroutine_int.h"
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index c8c4500..7e21e6f 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -17,8 +17,6 @@
*/
#include "qemu/osdep.h"
-
-#include "qemu-common.h"
#include "exec/target_page.h"
#include "migration.h"
#include "qemu-file.h"
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index e65c373..2ab2bf3 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -26,8 +26,6 @@
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qemu/iov.h"
-#include "qemu/sockets.h"
-#include "qemu/coroutine.h"
#include "migration.h"
#include "qemu-file.h"
#include "trace.h"
diff --git a/migration/ram.c b/migration/ram.c
index c1b4f4a..0baa1e0 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -26,14 +26,12 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "cpu.h"
#include <zlib.h>
#include "qapi-event.h"
#include "qemu/cutils.h"
#include "qemu/bitops.h"
#include "qemu/bitmap.h"
-#include "qemu/timer.h"
#include "qemu/main-loop.h"
#include "xbzrle.h"
#include "ram.h"
@@ -41,9 +39,7 @@
#include "migration/register.h"
#include "migration/misc.h"
#include "qemu-file.h"
-#include "migration/vmstate.h"
#include "postcopy-ram.h"
-#include "exec/address-spaces.h"
#include "migration/page_cache.h"
#include "qemu/error-report.h"
#include "trace.h"
@@ -2238,6 +2234,9 @@ void migrate_decompress_threads_create(void)
{
int i, thread_count;
+ if (!migrate_use_compression()) {
+ return;
+ }
thread_count = migrate_decompress_threads();
decompress_threads = g_new0(QemuThread, thread_count);
decomp_param = g_new0(DecompressParam, thread_count);
@@ -2259,6 +2258,9 @@ void migrate_decompress_threads_join(void)
{
int i, thread_count;
+ if (!migrate_use_compression()) {
+ return;
+ }
thread_count = migrate_decompress_threads();
for (i = 0; i < thread_count; i++) {
qemu_mutex_lock(&decomp_param[i].mutex);
@@ -2459,7 +2461,7 @@ static int ram_load_postcopy(QEMUFile *f)
static int ram_load(QEMUFile *f, void *opaque, int version_id)
{
- int flags = 0, ret = 0;
+ int flags = 0, ret = 0, invalid_flags = 0;
static uint64_t seq_iter;
int len = 0;
/*
@@ -2476,6 +2478,9 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
ret = -EINVAL;
}
+ if (!migrate_use_compression()) {
+ invalid_flags |= RAM_SAVE_FLAG_COMPRESS_PAGE;
+ }
/* This RCU critical section can be very long running.
* When RCU reclaims in the code start to become numerous,
* it will be necessary to reduce the granularity of this
@@ -2496,6 +2501,15 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
flags = addr & ~TARGET_PAGE_MASK;
addr &= TARGET_PAGE_MASK;
+ if (flags & invalid_flags) {
+ if (flags & invalid_flags & RAM_SAVE_FLAG_COMPRESS_PAGE) {
+ error_report("Received an unexpected compressed page");
+ }
+
+ ret = -EINVAL;
+ break;
+ }
+
if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
RAMBlock *block = ram_block_from_stream(f, flags);
diff --git a/migration/savevm.c b/migration/savevm.c
index 30cda2c..6bfd489 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -28,12 +28,8 @@
#include "qemu/osdep.h"
#include "hw/boards.h"
-#include "hw/hw.h"
-#include "hw/qdev.h"
#include "hw/xen/xen.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "qemu/timer.h"
#include "migration.h"
#include "migration/snapshot.h"
#include "migration/misc.h"
@@ -46,13 +42,11 @@
#include "postcopy-ram.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
-#include "qemu/queue.h"
#include "sysemu/cpus.h"
#include "exec/memory.h"
#include "exec/target_page.h"
#include "qmp-commands.h"
#include "trace.h"
-#include "qemu/bitops.h"
#include "qemu/iov.h"
#include "block/snapshot.h"
#include "qemu/cutils.h"
@@ -1110,7 +1104,8 @@ void qemu_savevm_state_complete_postcopy(QEMUFile *f)
qemu_fflush(f);
}
-void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only)
+int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only,
+ bool inactivate_disks)
{
QJSON *vmdesc;
int vmdesc_len;
@@ -1144,12 +1139,12 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only)
save_section_footer(f, se);
if (ret < 0) {
qemu_file_set_error(f, ret);
- return;
+ return -1;
}
}
if (iterable_only) {
- return;
+ return 0;
}
vmdesc = qjson_new();
@@ -1179,6 +1174,15 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only)
json_end_object(vmdesc);
}
+ if (inactivate_disks) {
+ /* Inactivate before sending QEMU_VM_EOF so that the
+ * bdrv_invalidate_cache_all() on the other end won't fail. */
+ ret = bdrv_inactivate_all();
+ if (ret) {
+ qemu_file_set_error(f, ret);
+ return ret;
+ }
+ }
if (!in_postcopy) {
/* Postcopy stream will still be going */
qemu_put_byte(f, QEMU_VM_EOF);
@@ -1196,6 +1200,7 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only)
qjson_destroy(vmdesc);
qemu_fflush(f);
+ return 0;
}
/* Give an estimate of the amount left to be transferred,
@@ -1269,7 +1274,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
ret = qemu_file_get_error(f);
if (ret == 0) {
- qemu_savevm_state_complete_precopy(f, false);
+ qemu_savevm_state_complete_precopy(f, false, false);
ret = qemu_file_get_error(f);
}
qemu_savevm_state_cleanup();
diff --git a/migration/savevm.h b/migration/savevm.h
index 45b59c1..5a2ed11 100644
--- a/migration/savevm.h
+++ b/migration/savevm.h
@@ -35,7 +35,8 @@ void qemu_savevm_state_header(QEMUFile *f);
int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy);
void qemu_savevm_state_cleanup(void);
void qemu_savevm_state_complete_postcopy(QEMUFile *f);
-void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only);
+int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only,
+ bool inactivate_disks);
void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size,
uint64_t *res_non_postcopiable,
uint64_t *res_postcopiable);
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index a4d31df..a4028fb 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -149,7 +149,7 @@ typedef struct CPUS390XState {
CPU_COMMON
uint32_t cpu_num;
- uint32_t machine_type;
+ uint64_t cpuid;
uint64_t tod_offset;
uint64_t tod_basetime;
@@ -460,11 +460,6 @@ static inline bool get_per_in_range(CPUS390XState *env, uint64_t addr)
}
#ifndef CONFIG_USER_ONLY
-/* In several cases of runtime exceptions, we havn't recorded the true
- instruction length. Use these codes when raising exceptions in order
- to re-compute the length by examining the insn in memory. */
-#define ILEN_LATER 0x20
-#define ILEN_LATER_INC 0x21
void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen);
#endif
@@ -1133,6 +1128,8 @@ uint32_t set_cc_nz_f128(float128 v);
int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3);
void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3);
#endif
+/* automatically detect the instruction length */
+#define ILEN_AUTO 0xff
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen);
void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
uintptr_t retaddr);
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index b34318f..478bcc6 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -737,8 +737,6 @@ static inline void apply_cpu_model(const S390CPUModel *model, Error **errp)
if (kvm_enabled()) {
kvm_s390_apply_cpu_model(model, errp);
- } else if (model) {
- /* FIXME TCG - use data for stdip/stfl */
}
if (!*errp) {
@@ -786,6 +784,12 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
}
apply_cpu_model(cpu->model, errp);
+
+ cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model);
+ if (tcg_enabled()) {
+ /* basic mode, write the cpu address into the first 4 bit of the ID */
+ cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.cpu_num);
+ }
}
static void get_feature(Object *obj, Visitor *v, const char *name,
diff --git a/target/s390x/helper.c b/target/s390x/helper.c
index a8d20c5..aef09e1 100644
--- a/target/s390x/helper.c
+++ b/target/s390x/helper.c
@@ -204,7 +204,7 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr,
if (raddr > ram_size) {
DPRINTF("%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
(uint64_t)raddr, (uint64_t)ram_size);
- trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_LATER_INC);
+ trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
return 1;
}
@@ -331,16 +331,42 @@ static void do_program_interrupt(CPUS390XState *env)
LowCore *lowcore;
int ilen = env->int_pgm_ilen;
- switch (ilen) {
- case ILEN_LATER:
- ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
- break;
- case ILEN_LATER_INC:
+ if (ilen == ILEN_AUTO) {
ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
+ }
+ assert(ilen == 2 || ilen == 4 || ilen == 6);
+
+ switch (env->int_pgm_code) {
+ case PGM_PER:
+ if (env->per_perc_atmid & PER_CODE_EVENT_NULLIFICATION) {
+ break;
+ }
+ /* FALL THROUGH */
+ case PGM_OPERATION:
+ case PGM_PRIVILEGED:
+ case PGM_EXECUTE:
+ case PGM_PROTECTION:
+ case PGM_ADDRESSING:
+ case PGM_SPECIFICATION:
+ case PGM_DATA:
+ case PGM_FIXPT_OVERFLOW:
+ case PGM_FIXPT_DIVIDE:
+ case PGM_DEC_OVERFLOW:
+ case PGM_DEC_DIVIDE:
+ case PGM_HFP_EXP_OVERFLOW:
+ case PGM_HFP_EXP_UNDERFLOW:
+ case PGM_HFP_SIGNIFICANCE:
+ case PGM_HFP_DIVIDE:
+ case PGM_TRANS_SPEC:
+ case PGM_SPECIAL_OP:
+ case PGM_OPERAND:
+ case PGM_HFP_SQRT:
+ case PGM_PC_TRANS_SPEC:
+ case PGM_ALET_SPEC:
+ case PGM_MONITOR:
+ /* advance the PSW if our exception is not nullifying */
env->psw.addr += ilen;
break;
- default:
- assert(ilen == 2 || ilen == 4 || ilen == 6);
}
qemu_log_mask(CPU_LOG_INT, "%s: code=0x%x ilen=%d\n",
@@ -737,6 +763,6 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
if (retaddr) {
cpu_restore_state(cs, retaddr);
}
- program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER);
+ program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO);
}
#endif /* CONFIG_USER_ONLY */
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 73dd05d..d089707 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -960,7 +960,7 @@
/* STORE CPU ADDRESS */
C(0xb212, STAP, S, Z, la2, 0, new, m1_16, stap, 0)
/* STORE CPU ID */
- C(0xb202, STIDP, S, Z, la2, 0, new, m1_64, stidp, 0)
+ C(0xb202, STIDP, S, Z, la2, 0, new, 0, stidp, 0)
/* STORE CPU TIMER */
C(0xb209, STPT, S, Z, la2, 0, new, m1_64, stpt, 0)
/* STORE FACILITY LIST */
diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index edcdf17..b508101 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -54,19 +54,14 @@ void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
uintptr_t retaddr)
{
CPUState *cs = CPU(s390_env_get_cpu(env));
- int t;
cs->exception_index = EXCP_PGM;
env->int_pgm_code = excp;
+ env->int_pgm_ilen = ILEN_AUTO;
/* Use the (ultimate) callers address to find the insn that trapped. */
cpu_restore_state(cs, retaddr);
- /* Advance past the insn. */
- t = cpu_ldub_code(env, env->psw.addr);
- env->int_pgm_ilen = t = get_ilen(t);
- env->psw.addr += t;
-
cpu_loop_exit(cs);
}
@@ -199,12 +194,12 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
IplParameterBlock *iplb;
if (env->psw.mask & PSW_MASK_PSTATE) {
- program_interrupt(env, PGM_PRIVILEGED, ILEN_LATER_INC);
+ program_interrupt(env, PGM_PRIVILEGED, ILEN_AUTO);
return;
}
if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
- program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
+ program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO);
return;
}
@@ -229,12 +224,12 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
break;
case 5:
if ((r1 & 1) || (addr & 0x0fffULL)) {
- program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
+ program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO);
return;
}
if (!address_space_access_valid(&address_space_memory, addr,
sizeof(IplParameterBlock), false)) {
- program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);
+ program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO);
return;
}
iplb = g_malloc0(sizeof(IplParameterBlock));
@@ -258,12 +253,12 @@ out:
return;
case 6:
if ((r1 & 1) || (addr & 0x0fffULL)) {
- program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
+ program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO);
return;
}
if (!address_space_access_valid(&address_space_memory, addr,
sizeof(IplParameterBlock), true)) {
- program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);
+ program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO);
return;
}
iplb = s390_ipl_get_iplb();
@@ -307,7 +302,7 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
}
if (r) {
- program_interrupt(env, PGM_OPERATION, ILEN_LATER_INC);
+ program_interrupt(env, PGM_OPERATION, ILEN_AUTO);
}
}
@@ -383,6 +378,7 @@ uint64_t HELPER(stpt)(CPUS390XState *env)
uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
uint64_t r0, uint64_t r1)
{
+ S390CPU *cpu = s390_env_get_cpu(env);
int cc = 0;
int sel1, sel2;
@@ -402,12 +398,14 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
if ((sel1 == 1) && (sel2 == 1)) {
/* Basic Machine Configuration */
struct sysib_111 sysib;
+ char type[5] = {};
memset(&sysib, 0, sizeof(sysib));
ebcdic_put(sysib.manuf, "QEMU ", 16);
- /* same as machine type number in STORE CPU ID */
- ebcdic_put(sysib.type, "QEMU", 4);
- /* same as model number in STORE CPU ID */
+ /* same as machine type number in STORE CPU ID, but in EBCDIC */
+ snprintf(type, ARRAY_SIZE(type), "%X", cpu->model->def->type);
+ ebcdic_put(sysib.type, type, 4);
+ /* model number (not stored in STORE CPU ID for z/Architecure) */
ebcdic_put(sysib.model, "QEMU ", 16);
ebcdic_put(sysib.sequence, "QEMU ", 16);
ebcdic_put(sysib.plant, "QEMU", 4);
@@ -668,6 +666,7 @@ void HELPER(per_ifetch)(CPUS390XState *env, uint64_t addr)
if (env->cregs[9] & PER_CR9_EVENT_NULLIFICATION) {
CPUState *cs = CPU(s390_env_get_cpu(env));
+ env->per_perc_atmid |= PER_CODE_EVENT_NULLIFICATION;
env->int_pgm_code = PGM_PER;
env->int_pgm_ilen = get_ilen(cpu_ldub_code(env, addr));
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 501e390..a873dc4 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -79,13 +79,13 @@ static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
return;
}
- trigger_access_exception(env, PGM_PROTECTION, ILEN_LATER_INC, tec);
+ trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, tec);
}
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
uint32_t type, uint64_t asc, int rw, bool exc)
{
- int ilen = ILEN_LATER;
+ int ilen = ILEN_AUTO;
uint64_t tec;
tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | asc >> 46;
@@ -431,7 +431,7 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
for (i = 0; i < nr_pages; i++) {
/* Low-address protection? */
if (lowprot && (addr < 512 || (addr >= 4096 && addr < 4096 + 512))) {
- trigger_access_exception(env, PGM_PROTECTION, ILEN_LATER_INC, 0);
+ trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, 0);
return -EACCES;
}
ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, true);
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 95f91d4..8c055b7 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -355,8 +355,7 @@ static void gen_program_exception(DisasContext *s, int code)
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_ilen));
tcg_temp_free_i32(tmp);
- /* Advance past instruction. */
- s->pc = s->next_pc;
+ /* update the psw */
update_psw_addr(s);
/* Save off cc. */
@@ -3877,14 +3876,9 @@ static ExitStatus op_stctl(DisasContext *s, DisasOps *o)
static ExitStatus op_stidp(DisasContext *s, DisasOps *o)
{
- TCGv_i64 t1 = tcg_temp_new_i64();
-
check_privileged(s);
- tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
- tcg_gen_ld32u_i64(t1, cpu_env, offsetof(CPUS390XState, machine_type));
- tcg_gen_deposit_i64(o->out, o->out, t1, 32, 32);
- tcg_temp_free_i64(t1);
-
+ tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, cpuid));
+ tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN);
return NO_EXIT;
}
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 004ec27..1f010d3 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -52,6 +52,8 @@
/* macOS 10.12 deprecated many constants, #define the new names for older SDKs */
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
#define NSEventMaskAny NSAnyEventMask
+#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
+#define NSEventModifierFlagShift NSShiftKeyMask
#define NSEventModifierFlagCommand NSCommandKeyMask
#define NSEventModifierFlagControl NSControlKeyMask
#define NSEventModifierFlagOption NSAlternateKeyMask
@@ -268,7 +270,7 @@ static void handleAnyDeviceErrors(Error * err)
NSWindow *fullScreenWindow;
float cx,cy,cw,ch,cdx,cdy;
CGDataProviderRef dataProviderRef;
- int modifiers_state[256];
+ BOOL modifiers_state[256];
BOOL isMouseGrabbed;
BOOL isFullscreen;
BOOL isAbsoluteEnabled;
@@ -536,18 +538,59 @@ QemuCocoaView *cocoaView;
}
}
+- (void) toggleModifier: (int)keycode {
+ // Toggle the stored state.
+ modifiers_state[keycode] = !modifiers_state[keycode];
+ // Send a keyup or keydown depending on the state.
+ qemu_input_event_send_key_qcode(dcl->con, keycode, modifiers_state[keycode]);
+}
+
+- (void) toggleStatefulModifier: (int)keycode {
+ // Toggle the stored state.
+ modifiers_state[keycode] = !modifiers_state[keycode];
+ // Generate keydown and keyup.
+ qemu_input_event_send_key_qcode(dcl->con, keycode, true);
+ qemu_input_event_send_key_qcode(dcl->con, keycode, false);
+}
+
- (void) handleEvent:(NSEvent *)event
{
COCOA_DEBUG("QemuCocoaView: handleEvent\n");
int buttons = 0;
- int keycode;
+ int keycode = 0;
bool mouse_event = false;
NSPoint p = [event locationInWindow];
switch ([event type]) {
case NSEventTypeFlagsChanged:
- keycode = cocoa_keycode_to_qemu([event keyCode]);
+ if ([event keyCode] == 0) {
+ // When the Cocoa keyCode is zero that means keys should be
+ // synthesized based on the values in in the eventModifiers
+ // bitmask.
+
+ if (qemu_console_is_graphic(NULL)) {
+ NSEventModifierFlags modifiers = [event modifierFlags];
+
+ if (!!(modifiers & NSEventModifierFlagCapsLock) != !!modifiers_state[Q_KEY_CODE_CAPS_LOCK]) {
+ [self toggleStatefulModifier:Q_KEY_CODE_CAPS_LOCK];
+ }
+ if (!!(modifiers & NSEventModifierFlagShift) != !!modifiers_state[Q_KEY_CODE_SHIFT]) {
+ [self toggleModifier:Q_KEY_CODE_SHIFT];
+ }
+ if (!!(modifiers & NSEventModifierFlagControl) != !!modifiers_state[Q_KEY_CODE_CTRL]) {
+ [self toggleModifier:Q_KEY_CODE_CTRL];
+ }
+ if (!!(modifiers & NSEventModifierFlagOption) != !!modifiers_state[Q_KEY_CODE_ALT]) {
+ [self toggleModifier:Q_KEY_CODE_ALT];
+ }
+ if (!!(modifiers & NSEventModifierFlagCommand) != !!modifiers_state[Q_KEY_CODE_META_L]) {
+ [self toggleModifier:Q_KEY_CODE_META_L];
+ }
+ }
+ } else {
+ keycode = cocoa_keycode_to_qemu([event keyCode]);
+ }
if ((keycode == Q_KEY_CODE_META_L || keycode == Q_KEY_CODE_META_R)
&& !isMouseGrabbed) {
@@ -559,16 +602,9 @@ QemuCocoaView *cocoaView;
// emulate caps lock and num lock keydown and keyup
if (keycode == Q_KEY_CODE_CAPS_LOCK ||
keycode == Q_KEY_CODE_NUM_LOCK) {
- qemu_input_event_send_key_qcode(dcl->con, keycode, true);
- qemu_input_event_send_key_qcode(dcl->con, keycode, false);
+ [self toggleStatefulModifier:keycode];
} else if (qemu_console_is_graphic(NULL)) {
- if (modifiers_state[keycode] == 0) { // keydown
- qemu_input_event_send_key_qcode(dcl->con, keycode, true);
- modifiers_state[keycode] = 1;
- } else { // keyup
- qemu_input_event_send_key_qcode(dcl->con, keycode, false);
- modifiers_state[keycode] = 0;
- }
+ [self toggleModifier:keycode];
}
}
diff --git a/ui/spice-core.c b/ui/spice-core.c
index a087ad5..182f550 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -847,6 +847,7 @@ void qemu_spice_init(void)
exit(1);
}
display_opengl = 1;
+ spice_opengl = 1;
}
#endif
}
diff --git a/ui/spice-display.c b/ui/spice-display.c
index b353445..042292c 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -27,6 +27,7 @@
#include "ui/spice-display.h"
static int debug = 0;
+bool spice_opengl;
static void GCC_FMT_ATTR(2, 3) dprint(int level, const char *fmt, ...)
{
@@ -1013,7 +1014,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)
ssd->dcl.ops = &display_listener_ops;
#ifdef HAVE_SPICE_GL
- if (display_opengl) {
+ if (spice_opengl) {
ssd->dcl.ops = &display_listener_gl_ops;
ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
diff --git a/ui/spice-input.c b/ui/spice-input.c
index 86293dd..9185802 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -87,7 +87,7 @@ static void kbd_leds(void *opaque, int ledstate)
if (ledstate & QEMU_CAPS_LOCK_LED) {
kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK;
}
- spice_server_kbd_leds(&kbd->sin, ledstate);
+ spice_server_kbd_leds(&kbd->sin, kbd->ledstate);
}
/* mouse bits */