Blame 0224-hw-qxl-support-client-monitor-configuration-via-devi.patch

Hans de Goede 93b7e3
From 3ad6b56cb328a01150fc9a61ee7f4300af2a0912 Mon Sep 17 00:00:00 2001
Hans de Goede 93b7e3
From: Alon Levy <alevy@redhat.com>
Hans de Goede 93b7e3
Date: Wed, 12 Sep 2012 16:13:28 +0300
Hans de Goede 93b7e3
Subject: [PATCH 224/293] hw/qxl: support client monitor configuration via
Hans de Goede 93b7e3
 device
Hans de Goede 93b7e3
Hans de Goede 93b7e3
Until now we used only the agent to change the monitor count and each
Hans de Goede 93b7e3
monitor resolution. This patch introduces the qemu part of using the
Hans de Goede 93b7e3
device as the mediator instead of the agent via virtio-serial.
Hans de Goede 93b7e3
Hans de Goede 93b7e3
Spice (>=0.11.5) calls the new QXLInterface::client_monitors_config,
Hans de Goede 93b7e3
which returns wether the interrupt is enabled, and if so and given a non
Hans de Goede 93b7e3
NULL monitors config will
Hans de Goede 93b7e3
generate an interrupt QXL_INTERRUPT_CLIENT_MONITORS_CONFIG with crc
Hans de Goede 93b7e3
checksum for the guest to verify a second call hasn't interfered.
Hans de Goede 93b7e3
Hans de Goede 93b7e3
The maximal number of monitors is limited on the QXLRom to 64.
Hans de Goede 93b7e3
Hans de Goede 93b7e3
Signed-off-by: Alon Levy <alevy@redhat.com>
Hans de Goede 93b7e3
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede 93b7e3
---
Hans de Goede 93b7e3
 configure    |  7 ++++++
Hans de Goede 93b7e3
 hw/qxl.c     | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hans de Goede 93b7e3
 trace-events |  6 ++++-
Hans de Goede 93b7e3
 3 files changed, 91 insertions(+), 1 deletion(-)
Hans de Goede 93b7e3
Hans de Goede 93b7e3
diff --git a/configure b/configure
Hans de Goede 93b7e3
index 0bfef84..ebe8b1c 100755
Hans de Goede 93b7e3
--- a/configure
Hans de Goede 93b7e3
+++ b/configure
Hans de Goede 93b7e3
@@ -2716,6 +2716,9 @@ EOF
Hans de Goede 93b7e3
     if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then
Hans de Goede 93b7e3
         spice_qxl_io_monitors_config_async="yes"
Hans de Goede 93b7e3
     fi
Hans de Goede 93b7e3
+    if $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1; then
Hans de Goede 93b7e3
+        spice_qxl_client_monitors_config="yes"
Hans de Goede 93b7e3
+    fi
Hans de Goede 93b7e3
   else
Hans de Goede 93b7e3
     if test "$spice" = "yes" ; then
Hans de Goede 93b7e3
       feature_not_found "spice"
Hans de Goede 93b7e3
@@ -3457,6 +3460,10 @@ if test "$spice_qxl_io_monitors_config_async" = "yes" ; then
Hans de Goede 93b7e3
   echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak
Hans de Goede 93b7e3
 fi
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
+if test "$spice_qxl_client_monitors_config" = "yes" ; then
Hans de Goede 93b7e3
+  echo "CONFIG_QXL_CLIENT_MONITORS_CONFIG=y" >> $config_host_mak
Hans de Goede 93b7e3
+fi
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
 if test "$smartcard" = "yes" ; then
Hans de Goede 93b7e3
   echo "CONFIG_SMARTCARD=y" >> $config_host_mak
Hans de Goede 93b7e3
 fi
Hans de Goede 93b7e3
diff --git a/hw/qxl.c b/hw/qxl.c
Hans de Goede 93b7e3
index 1ef117a..0695872 100644
Hans de Goede 93b7e3
--- a/hw/qxl.c
Hans de Goede 93b7e3
+++ b/hw/qxl.c
Hans de Goede 93b7e3
@@ -18,6 +18,8 @@
Hans de Goede 93b7e3
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
Hans de Goede 93b7e3
  */
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
+#include <zlib.h>
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
 #include "qemu-common.h"
Hans de Goede 93b7e3
 #include "qemu-timer.h"
Hans de Goede 93b7e3
 #include "qemu-queue.h"
Hans de Goede 93b7e3
@@ -971,6 +973,79 @@ static void interface_set_client_capabilities(QXLInstance *sin,
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
 #endif
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
+#if defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) \
Hans de Goede 93b7e3
+    && SPICE_SERVER_VERSION >= 0x000b05
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
+static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
Hans de Goede 93b7e3
+{
Hans de Goede 93b7e3
+    /*
Hans de Goede 93b7e3
+     * zlib xors the seed with 0xffffffff, and xors the result
Hans de Goede 93b7e3
+     * again with 0xffffffff; Both are not done with linux's crc32,
Hans de Goede 93b7e3
+     * which we want to be compatible with, so undo that.
Hans de Goede 93b7e3
+     */
Hans de Goede 93b7e3
+    return crc32(0xffffffff, p, len) ^ 0xffffffff;
Hans de Goede 93b7e3
+}
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
+/* called from main context only */
Hans de Goede 93b7e3
+static int interface_client_monitors_config(QXLInstance *sin,
Hans de Goede 93b7e3
+                                        VDAgentMonitorsConfig *monitors_config)
Hans de Goede 93b7e3
+{
Hans de Goede 93b7e3
+    PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
Hans de Goede 93b7e3
+    QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
Hans de Goede 93b7e3
+    int i;
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
+    /*
Hans de Goede 93b7e3
+     * Older windows drivers set int_mask to 0 when their ISR is called,
Hans de Goede 93b7e3
+     * then later set it to ~0. So it doesn't relate to the actual interrupts
Hans de Goede 93b7e3
+     * handled. However, they are old, so clearly they don't support this
Hans de Goede 93b7e3
+     * interrupt
Hans de Goede 93b7e3
+     */
Hans de Goede 93b7e3
+    if (qxl->ram->int_mask == 0 || qxl->ram->int_mask == ~0 ||
Hans de Goede 93b7e3
+        !(qxl->ram->int_mask & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG)) {
Hans de Goede 93b7e3
+        trace_qxl_client_monitors_config_unsupported_by_guest(qxl->id,
Hans de Goede 93b7e3
+                                                            qxl->ram->int_mask,
Hans de Goede 93b7e3
+                                                            monitors_config);
Hans de Goede 93b7e3
+        return 0;
Hans de Goede 93b7e3
+    }
Hans de Goede 93b7e3
+    if (!monitors_config) {
Hans de Goede 93b7e3
+        return 1;
Hans de Goede 93b7e3
+    }
Hans de Goede 93b7e3
+    memset(&rom->client_monitors_config, 0,
Hans de Goede 93b7e3
+           sizeof(rom->client_monitors_config));
Hans de Goede 93b7e3
+    rom->client_monitors_config.count = monitors_config->num_of_monitors;
Hans de Goede 93b7e3
+    /* monitors_config->flags ignored */
Hans de Goede 93b7e3
+    if (rom->client_monitors_config.count >=
Hans de Goede 93b7e3
+            ARRAY_SIZE(rom->client_monitors_config.heads)) {
Hans de Goede 93b7e3
+        trace_qxl_client_monitors_config_capped(qxl->id,
Hans de Goede 93b7e3
+                                monitors_config->num_of_monitors,
Hans de Goede 93b7e3
+                                ARRAY_SIZE(rom->client_monitors_config.heads));
Hans de Goede 93b7e3
+        rom->client_monitors_config.count =
Hans de Goede 93b7e3
+            ARRAY_SIZE(rom->client_monitors_config.heads);
Hans de Goede 93b7e3
+    }
Hans de Goede 93b7e3
+    for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
Hans de Goede 93b7e3
+        VDAgentMonConfig *monitor = &monitors_config->monitors[i];
Hans de Goede 93b7e3
+        QXLURect *rect = &rom->client_monitors_config.heads[i];
Hans de Goede 93b7e3
+        /* monitor->depth ignored */
Hans de Goede 93b7e3
+        rect->left = monitor->x;
Hans de Goede 93b7e3
+        rect->top = monitor->y;
Hans de Goede 93b7e3
+        rect->right = monitor->x + monitor->width;
Hans de Goede 93b7e3
+        rect->bottom = monitor->y + monitor->height;
Hans de Goede 93b7e3
+    }
Hans de Goede 93b7e3
+    rom->client_monitors_config_crc = qxl_crc32(
Hans de Goede 93b7e3
+            (const uint8_t *)&rom->client_monitors_config,
Hans de Goede 93b7e3
+            sizeof(rom->client_monitors_config));
Hans de Goede 93b7e3
+    trace_qxl_client_monitors_config_crc(qxl->id,
Hans de Goede 93b7e3
+            sizeof(rom->client_monitors_config),
Hans de Goede 93b7e3
+            rom->client_monitors_config_crc);
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
+    trace_qxl_interrupt_client_monitors_config(qxl->id,
Hans de Goede 93b7e3
+                        rom->client_monitors_config.count,
Hans de Goede 93b7e3
+                        rom->client_monitors_config.heads);
Hans de Goede 93b7e3
+    qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG);
Hans de Goede 93b7e3
+    return 1;
Hans de Goede 93b7e3
+}
Hans de Goede 93b7e3
+#endif
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
 static const QXLInterface qxl_interface = {
Hans de Goede 93b7e3
     .base.type               = SPICE_INTERFACE_QXL,
Hans de Goede 93b7e3
     .base.description        = "qxl gpu",
Hans de Goede 93b7e3
@@ -995,6 +1070,10 @@ static const QXLInterface qxl_interface = {
Hans de Goede 93b7e3
 #if SPICE_SERVER_VERSION >= 0x000b04
Hans de Goede 93b7e3
     .set_client_capabilities = interface_set_client_capabilities,
Hans de Goede 93b7e3
 #endif
Hans de Goede 93b7e3
+#if SPICE_SERVER_VERSION >= 0x000b05 && \
Hans de Goede 93b7e3
+    defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG)
Hans de Goede 93b7e3
+    .client_monitors_config = interface_client_monitors_config,
Hans de Goede 93b7e3
+#endif
Hans de Goede 93b7e3
 };
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
 static void qxl_enter_vga_mode(PCIQXLDevice *d)
Hans de Goede 93b7e3
diff --git a/trace-events b/trace-events
Hans de Goede 93b7e3
index 0ce69d6..1b19988 100644
Hans de Goede 93b7e3
--- a/trace-events
Hans de Goede 93b7e3
+++ b/trace-events
Hans de Goede 93b7e3
@@ -924,7 +924,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d
Hans de Goede 93b7e3
 qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
Hans de Goede 93b7e3
 qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
Hans de Goede 93b7e3
 qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
Hans de Goede 93b7e3
-qxl_io_log(int qid, const uint8_t *str) "%d %s"
Hans de Goede 93b7e3
+qxl_io_log(int qid, const uint8_t *log_buf) "%d %s"
Hans de Goede 93b7e3
 qxl_io_read_unexpected(int qid) "%d"
Hans de Goede 93b7e3
 qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)"
Hans de Goede 93b7e3
 qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d"
Hans de Goede 93b7e3
@@ -968,6 +968,10 @@ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dir
Hans de Goede 93b7e3
 qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
Hans de Goede 93b7e3
 qxl_send_events(int qid, uint32_t events) "%d %d"
Hans de Goede 93b7e3
 qxl_set_guest_bug(int qid) "%d"
Hans de Goede 93b7e3
+qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p"
Hans de Goede 93b7e3
+qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p"
Hans de Goede 93b7e3
+qxl_client_monitors_config_capped(int qid, int requested, int limit) "%d %d %d"
Hans de Goede 93b7e3
+qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32) "%d %u %u"
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
 # hw/qxl-render.c
Hans de Goede 93b7e3
 qxl_render_blit_guest_primary_initialized(void) ""
Hans de Goede 93b7e3
-- 
Hans de Goede 93b7e3
1.7.12
Hans de Goede 93b7e3