Patchwork [1/2] qxl: create slots on post_load in any state

login
register
mail settings
Submitter Alon Levy
Date Oct. 18, 2011, 3:26 p.m.
Message ID <1318951567-12418-1-git-send-email-alevy@redhat.com>
Download mbox | patch
Permalink /patch/120449/
State New
Headers show

Comments

Alon Levy - Oct. 18, 2011, 3:26 p.m.
If we migrate when the device is not in a native state the guest
still believes the slots are created, and will cause operations
that reference the slots, causing a "panic: virtual address out of range"
on the first of them. Easy to see by migrating in vga mode (with
a driver loaded, for instance windows cmd window in full screen mode)
and then exiting vga mode back to native mode will cause said panic.

Fixed by doing the slot recreation unconditionally at post_load, and
using the delta value. Next patch makes sure we actually migrate that
delta.

RHBZ: 740547

Signed-off-by: Alon Levy <alevy@redhat.com>
---
 hw/qxl.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)
Gerd Hoffmann - Oct. 19, 2011, 8:28 a.m.
On 10/18/11 17:26, Alon Levy wrote:
> If we migrate when the device is not in a native state the guest
> still believes the slots are created, and will cause operations
> that reference the slots, causing a "panic: virtual address out of range"
> on the first of them. Easy to see by migrating in vga mode (with
> a driver loaded, for instance windows cmd window in full screen mode)
> and then exiting vga mode back to native mode will cause said panic.
>
> Fixed by doing the slot recreation unconditionally at post_load, and
> using the delta value. Next patch makes sure we actually migrate that
> delta.

I don't think we have to save the delta value.  The delta is used only 
in compat mode.  In compat mode the guest doesn't create memory slots, 
instead qxl does that (in qxl_set_mode).

I think you can just skip the slot re-creation in compat mode and let 
qxl_set_mode (which is called later in post_load) handle it.

cheers,
   Gerd
Alon Levy - Oct. 19, 2011, 9:55 a.m.
On Wed, Oct 19, 2011 at 10:28:57AM +0200, Gerd Hoffmann wrote:
> On 10/18/11 17:26, Alon Levy wrote:
> >If we migrate when the device is not in a native state the guest
> >still believes the slots are created, and will cause operations
> >that reference the slots, causing a "panic: virtual address out of range"
> >on the first of them. Easy to see by migrating in vga mode (with
> >a driver loaded, for instance windows cmd window in full screen mode)
> >and then exiting vga mode back to native mode will cause said panic.
> >
> >Fixed by doing the slot recreation unconditionally at post_load, and
> >using the delta value. Next patch makes sure we actually migrate that
> >delta.
> 
> I don't think we have to save the delta value.  The delta is used
> only in compat mode.  In compat mode the guest doesn't create memory
> slots, instead qxl does that (in qxl_set_mode).
> 
> I think you can just skip the slot re-creation in compat mode and
> let qxl_set_mode (which is called later in post_load) handle it.
> 

My bad, missed that. Will resend.

> cheers,
>   Gerd
>

Patch

diff --git a/hw/qxl.c b/hw/qxl.c
index 03848ed..4e9f39f 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1684,6 +1684,14 @@  static int qxl_post_load(void *opaque, int version)
         qxl_mode_to_string(d->mode));
     newmode = d->mode;
     d->mode = QXL_MODE_UNDEFINED;
+    for (i = 0; i < NUM_MEMSLOTS; i++) {
+        if (!d->guest_slots[i].active) {
+            continue;
+        }
+        dprint(d, 1, "%s: restoring guest slot %d delta %"PRIu64"\n",
+               __func__, i, d->guest_slots[i].delta);
+        qxl_add_memslot(d, i, d->guest_slots[i].delta, QXL_SYNC);
+    }
     switch (newmode) {
     case QXL_MODE_UNDEFINED:
         break;
@@ -1691,12 +1699,6 @@  static int qxl_post_load(void *opaque, int version)
         qxl_enter_vga_mode(d);
         break;
     case QXL_MODE_NATIVE:
-        for (i = 0; i < NUM_MEMSLOTS; i++) {
-            if (!d->guest_slots[i].active) {
-                continue;
-            }
-            qxl_add_memslot(d, i, 0, QXL_SYNC);
-        }
         qxl_create_guest_primary(d, 1, QXL_SYNC);
 
         /* replay surface-create and cursor-set commands */