summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Tian <kevin.tian@intel.com>2010-06-29 08:54:03 +0800
committerRichard Purdie <rpurdie@linux.intel.com>2010-06-29 12:34:38 +0100
commit9207cd40153148f71788d30697a055fe846e8927 (patch)
tree08d8c79bdfd8eb6078822df36f60ab79c20b6506
parentbb3e4dda5d85402fadcecc97589ea4e452c36c98 (diff)
downloadpoky-9207cd40153148f71788d30697a055fe846e8927.tar.gz
qemu: fix VMware VGA depth calculation error
VMware SVGA presents to the guest with the depth of the host surface it renders to, and rejects to work if the two sides are mismatched. One problem is that current VMware VGA may calculate a wrong host depth, and then memcpy from virtual framebuffer to host surface may trigger segmentation fault. For example, when launching Qemu in a VNC connection, VMware SVGA thinks depth as '32', however the actual depth of VNC is '16'. The fault also happens when the host depth is not 32 bit. Qemu <4b5db3749c5fdba93e1ac0e8748c9a9a1064319f> tempts to fix a similar issue, by changing from hard-coded 24bit depth to instead query the surface allocator (e.g. sdl). However it doesn't really work, because the point where query is invoked is earlier than the point where sdl is initialized. At query time, qemu uses a default surface allocator which, again, provides another hard-coded depth value - 32bit. So it happens to make VMware SVGA working on some hosts, but still fails in others. To solve this issue, this commit introduces a postcall interface to display surface, which is walked after surface allocators are actually initialized. At that point it's then safe to query host depth and present to the guest. Signed-off-by Kevin Tian <kevin.tian@intel.com>
-rw-r--r--meta/packages/qemu/qemu-0.12.4/qemu-vmware-vga-depth.patch115
-rw-r--r--meta/packages/qemu/qemu_0.12.4.bb5
-rw-r--r--meta/packages/qemu/qemu_git.bb5
3 files changed, 121 insertions, 4 deletions
diff --git a/meta/packages/qemu/qemu-0.12.4/qemu-vmware-vga-depth.patch b/meta/packages/qemu/qemu-0.12.4/qemu-vmware-vga-depth.patch
new file mode 100644
index 0000000000..43071868f3
--- /dev/null
+++ b/meta/packages/qemu/qemu-0.12.4/qemu-vmware-vga-depth.patch
@@ -0,0 +1,115 @@
1# fix VMware VGA driver depth calculation error, which may cause segmentation fault
2#
3# ktian1, 06/29/2010
4diff --git a/console.h b/console.h
5index dfc8ae4..05fbf17 100644
6--- a/console.h
7+++ b/console.h
8@@ -122,6 +122,12 @@ struct DisplayAllocator {
9 void (*free_displaysurface)(DisplaySurface *surface);
10 };
11
12+struct DisplayPostCallback {
13+ void (*postcall) (void *);
14+ void *parm;
15+ struct DisplayPostCallback *next;
16+};
17+
18 struct DisplayState {
19 struct DisplaySurface *surface;
20 void *opaque;
21@@ -129,6 +135,7 @@ struct DisplayState {
22
23 struct DisplayAllocator* allocator;
24 struct DisplayChangeListener* listeners;
25+ struct DisplayPostCallback* postcalls;
26
27 void (*mouse_set)(int x, int y, int on);
28 void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
29@@ -185,6 +192,12 @@ static inline void register_displaychangelistener(DisplayState *ds, DisplayChang
30 ds->listeners = dcl;
31 }
32
33+static inline void register_displaypostcallback(DisplayState *ds, DisplayPostCallback *dpc)
34+{
35+ dpc->next = ds->postcalls;
36+ ds->postcalls = dpc;
37+}
38+
39 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
40 {
41 struct DisplayChangeListener *dcl = s->listeners;
42diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
43index 01bb85b..d73cca6 100644
44--- a/hw/vmware_vga.c
45+++ b/hw/vmware_vga.c
46@@ -927,8 +927,9 @@ static void vmsvga_update_display(void *opaque)
47 }
48 }
49
50-static void vmsvga_reset(struct vmsvga_state_s *s)
51+static void vmsvga_reset(void *parm)
52 {
53+ struct vmsvga_state_s *s = (struct vmsvga_state_s *)parm;
54 s->index = 0;
55 s->enable = 0;
56 s->config = 0;
57@@ -1133,6 +1134,8 @@ static const VMStateDescription vmstate_vmware_vga = {
58
59 static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
60 {
61+ DisplayPostCallback *dpc;
62+
63 s->scratch_size = SVGA_SCRATCH_SIZE;
64 s->scratch = qemu_malloc(s->scratch_size * 4);
65
66@@ -1160,7 +1163,10 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
67
68 rom_add_vga(VGABIOS_FILENAME);
69
70- vmsvga_reset(s);
71+ dpc = qemu_mallocz(sizeof(DisplayPostCallback));
72+ dpc->postcall = vmsvga_reset;
73+ dpc->parm = s;
74+ register_displaypostcallback(s->vga.ds, dpc);
75 }
76
77 static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
78diff --git a/qemu-common.h b/qemu-common.h
79index a23afbc..19f107a 100644
80--- a/qemu-common.h
81+++ b/qemu-common.h
82@@ -198,6 +198,7 @@ typedef struct DisplayState DisplayState;
83 typedef struct DisplayChangeListener DisplayChangeListener;
84 typedef struct DisplaySurface DisplaySurface;
85 typedef struct DisplayAllocator DisplayAllocator;
86+typedef struct DisplayPostCallback DisplayPostCallback;
87 typedef struct PixelFormat PixelFormat;
88 typedef struct TextConsole TextConsole;
89 typedef TextConsole QEMUConsole;
90diff --git a/vl.c b/vl.c
91index 39182ea..9a3e9fd 100644
92--- a/vl.c
93+++ b/vl.c
94@@ -4863,6 +4863,7 @@ int main(int argc, char **argv, char **envp)
95 char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
96 DisplayState *ds;
97 DisplayChangeListener *dcl;
98+ DisplayPostCallback *dpc;
99 int cyls, heads, secs, translation;
100 QemuOpts *hda_opts = NULL, *opts;
101 int optind;
102@@ -6053,6 +6053,13 @@ int main(int argc, char **argv, char **envp)
103 }
104 dpy_resize(ds);
105
106+ dpc = ds->postcalls;
107+ while (dpc != NULL) {
108+ if (dpc->postcall != NULL)
109+ dpc->postcall(dpc->parm);
110+ dpc = dpc->next;
111+ }
112+
113 dcl = ds->listeners;
114 while (dcl != NULL) {
115 if (dcl->dpy_refresh != NULL) {
diff --git a/meta/packages/qemu/qemu_0.12.4.bb b/meta/packages/qemu/qemu_0.12.4.bb
index 20cc8e8a5a..7d158bf863 100644
--- a/meta/packages/qemu/qemu_0.12.4.bb
+++ b/meta/packages/qemu/qemu_0.12.4.bb
@@ -1,6 +1,6 @@
1require qemu.inc 1require qemu.inc
2 2
3PR = "r15" 3PR = "r16"
4 4
5FILESPATH = "${FILE_DIRNAME}/qemu-${PV}" 5FILESPATH = "${FILE_DIRNAME}/qemu-${PV}"
6FILESDIR = "${WORKDIR}" 6FILESDIR = "${WORKDIR}"
@@ -14,6 +14,7 @@ SRC_URI = "\
14 file://fix-nogl.patch \ 14 file://fix-nogl.patch \
15 file://qemugl-allow-glxcontext-release.patch \ 15 file://qemugl-allow-glxcontext-release.patch \
16 file://linker-flags.patch \ 16 file://linker-flags.patch \
17 file://init-info.patch" 17 file://init-info.patch \
18 file://qemu-vmware-vga-depth.patch"
18 19
19S = "${WORKDIR}/qemu-${PV}" 20S = "${WORKDIR}/qemu-${PV}"
diff --git a/meta/packages/qemu/qemu_git.bb b/meta/packages/qemu/qemu_git.bb
index b1468704ac..00b361063a 100644
--- a/meta/packages/qemu/qemu_git.bb
+++ b/meta/packages/qemu/qemu_git.bb
@@ -1,7 +1,7 @@
1require qemu.inc 1require qemu.inc
2 2
3PV = "0.12.4" 3PV = "0.12.4"
4PR = "r8" 4PR = "r9"
5 5
6FILESPATH = "${FILE_DIRNAME}/qemu-${PV}/:${FILE_DIRNAME}/qemu-git/" 6FILESPATH = "${FILE_DIRNAME}/qemu-${PV}/:${FILE_DIRNAME}/qemu-git/"
7FILESDIR = "${WORKDIR}" 7FILESDIR = "${WORKDIR}"
@@ -14,7 +14,8 @@ SRC_URI = "\
14 file://fix-dirent.patch \ 14 file://fix-dirent.patch \
15 file://fix-nogl.patch \ 15 file://fix-nogl.patch \
16 file://qemugl-allow-glxcontext-release.patch \ 16 file://qemugl-allow-glxcontext-release.patch \
17 file://linker-flags.patch" 17 file://linker-flags.patch \
18 file://qemu-vmware-vga-depth.patch"
18 19
19S = "${WORKDIR}/git" 20S = "${WORKDIR}/git"
20 21