summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorZhai Edwin <edwin.zhai@intel.com>2010-10-01 01:43:14 +0800
committerSaul Wold <Saul.Wold@intel.com>2010-09-30 12:32:10 -0700
commit27b68f9f4c178c60e7095001a7dda3864068c6ae (patch)
treeac28ee6f19f4b196bb09a9bc627a1af10766f88d /meta
parent7f17d12cfdcd975a777acf9fdf2b8e0ce701de05 (diff)
downloadpoky-27b68f9f4c178c60e7095001a7dda3864068c6ae.tar.gz
qemu: introduce vmware vga FIFO rewind patch to fix qemu hang
In some circumstance guest driver got interrupted before inserting all args for one command, so that qemu get an invalid args and hang. GL patch doesn't consume these missing args, which further cause FIFO disorder. This commit reverts wrong behavior of GL patch, and introduces a qemu upstream patch to rewind FIFO unpon detecting incomplete command. [BUGID #111] fixed by this. Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-devtools/qemu/qemu-0.12.4/vmware-vga-fifo-rewind.patch198
-rw-r--r--meta/recipes-devtools/qemu/qemu_0.12.4.bb3
2 files changed, 200 insertions, 1 deletions
diff --git a/meta/recipes-devtools/qemu/qemu-0.12.4/vmware-vga-fifo-rewind.patch b/meta/recipes-devtools/qemu/qemu-0.12.4/vmware-vga-fifo-rewind.patch
new file mode 100644
index 0000000000..ef92f54c8b
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu-0.12.4/vmware-vga-fifo-rewind.patch
@@ -0,0 +1,198 @@
1commit 4dedc07ffbbc66002e0fd2b97d5516fe6aca5eea
2Author: Andrzej Zaborowski <balrog@zabor.org>
3Date: Fri Sep 10 02:23:31 2010 +0200
4
5 vmware_vga: Add checks to deal with non-atomic fifo writes.
6
7 Janne Huttunen noticed that the FIFO end pointer is updated by the
8 guest after writing each word to the FIFO, at least the X.org driver
9 which is open does this. This means that there's no way for the
10 host to know if the guest is in the middle a write operation. Qemu
11 thus needs to read the beginning of the command up to when it's able
12 to tell how many words are expected for the given command. It will
13 abort reading and rewind the FIFO if there aren't enough words yet,
14 this should be relatively rare but it is suspected to have been the
15 cause of the occasional FIFO overrun that killed the display.
16
17Index: qemu-0.12.4/hw/vmware_vga.c
18===================================================================
19--- qemu-0.12.4.orig/hw/vmware_vga.c 2010-09-30 23:04:34.000000000 +0800
20+++ qemu-0.12.4/hw/vmware_vga.c 2010-10-01 01:17:02.000000000 +0800
21@@ -491,27 +491,37 @@
22
23 static uint32_t last_cmd;
24
25-static inline int vmsvga_fifo_empty(struct vmsvga_state_s *s)
26+static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
27 {
28+ int num;
29 if (!s->config || !s->enable)
30- return 1;
31- return (s->cmd->next_cmd == s->cmd->stop);
32+ return 0;
33+ num = CMD(next_cmd) - CMD(stop);
34+ if (num < 0)
35+ num += CMD(max) - CMD(min);
36+ return num >> 2;
37 }
38
39 static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)
40 {
41- int offset = CMD(stop);
42+ uint32_t cmd = s->fifo[CMD(stop) >> 2];
43
44+ /* If parameter is not available in FIFO, return 0 rather than random
45+ * value. Also update the stop as missing parameter will be inserted
46+ * soonly, else it will be treated as new command next time.
47+ * With rewinding in vmsvga_fifo_run, this unlikely happen.
48+ */
49 if (unlikely(s->cmd->next_cmd == s->cmd->stop)) {
50 fprintf(stderr, "%s: FIFO empty during CMD %i\n",
51 __FUNCTION__, last_cmd);
52- return 0x00000000;
53+ cmd = 0;
54 }
55
56- s->cmd->stop = cpu_to_le32(offset + 4);
57- if (offset + 4 >= CMD(max))
58+ s->cmd->stop = cpu_to_le32(CMD(stop) + 4);
59+ if (CMD(stop) >= CMD(max))
60 s->cmd->stop = s->cmd->min;
61- return s->fifo[offset >> 2];
62+
63+ return cmd;
64 }
65
66 static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s)
67@@ -522,13 +532,23 @@
68 static void vmsvga_fifo_run(struct vmsvga_state_s *s)
69 {
70 uint32_t colour;
71- int args = 0;
72+ int args, len;
73 int x, y, dx, dy, width, height;
74 struct vmsvga_cursor_definition_s cursor;
75- while (!vmsvga_fifo_empty(s))
76+ uint32_t cmd_start;
77+
78+ len = vmsvga_fifo_length(s);
79+ while (len > 0) {
80+ /* May need to go back to the start of the command if incomplete */
81+ cmd_start = s->cmd->stop;
82+
83 switch (last_cmd = vmsvga_fifo_read(s)) {
84 case SVGA_CMD_UPDATE:
85 case SVGA_CMD_UPDATE_VERBOSE:
86+ len -= 5;
87+ if (len <0)
88+ goto rewind;
89+
90 x = vmsvga_fifo_read(s);
91 y = vmsvga_fifo_read(s);
92 width = vmsvga_fifo_read(s);
93@@ -537,6 +557,10 @@
94 break;
95
96 case SVGA_CMD_RECT_FILL:
97+ len -= 6;
98+ if (len < 0)
99+ goto rewind;
100+
101 colour = vmsvga_fifo_read(s);
102 x = vmsvga_fifo_read(s);
103 y = vmsvga_fifo_read(s);
104@@ -546,10 +570,15 @@
105 vmsvga_fill_rect(s, colour, x, y, width, height);
106 break;
107 #else
108+ args = 0;
109 goto badcmd;
110 #endif
111
112 case SVGA_CMD_RECT_COPY:
113+ len -= 7;
114+ if (len < 0)
115+ goto rewind;
116+
117 x = vmsvga_fifo_read(s);
118 y = vmsvga_fifo_read(s);
119 dx = vmsvga_fifo_read(s);
120@@ -560,10 +589,15 @@
121 vmsvga_copy_rect(s, x, y, dx, dy, width, height);
122 break;
123 #else
124+ args = 0;
125 goto badcmd;
126 #endif
127
128 case SVGA_CMD_DEFINE_CURSOR:
129+ len -= 8;
130+ if (len < 0)
131+ goto rewind;
132+
133 cursor.id = vmsvga_fifo_read(s);
134 cursor.hot_x = vmsvga_fifo_read(s);
135 cursor.hot_y = vmsvga_fifo_read(s);
136@@ -572,11 +606,14 @@
137 vmsvga_fifo_read(s);
138 cursor.bpp = vmsvga_fifo_read(s);
139
140+ args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
141 if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
142- SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
143- args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
144+ SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image)
145 goto badcmd;
146- }
147+
148+ len -= args;
149+ if (len < 0)
150+ goto rewind;
151
152 for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args ++)
153 cursor.mask[args] = vmsvga_fifo_read_raw(s);
154@@ -595,6 +632,10 @@
155 * for so we can avoid FIFO desync if driver uses them illegally.
156 */
157 case SVGA_CMD_DEFINE_ALPHA_CURSOR:
158+ len -= 6;
159+ if (len < 0)
160+ goto rewind;
161+
162 vmsvga_fifo_read(s);
163 vmsvga_fifo_read(s);
164 vmsvga_fifo_read(s);
165@@ -609,6 +650,10 @@
166 args = 7;
167 goto badcmd;
168 case SVGA_CMD_DRAW_GLYPH_CLIPPED:
169+ len -= 4;
170+ if (len < 0)
171+ goto rewind;
172+
173 vmsvga_fifo_read(s);
174 vmsvga_fifo_read(s);
175 args = 7 + (vmsvga_fifo_read(s) >> 2);
176@@ -629,14 +674,22 @@
177 break; /* Nop */
178
179 default:
180+ args = 0;
181 badcmd:
182+ len -= args;
183+ if (len < 0)
184+ goto rewind;
185 while (args --)
186 vmsvga_fifo_read(s);
187 printf("%s: Unknown command 0x%02x in SVGA command FIFO\n",
188 __FUNCTION__, last_cmd);
189 break;
190+ rewind:
191+ s->cmd->stop = cmd_start;
192+ break;
193 }
194
195+ }
196 s->syncing = 0;
197 }
198
diff --git a/meta/recipes-devtools/qemu/qemu_0.12.4.bb b/meta/recipes-devtools/qemu/qemu_0.12.4.bb
index 86e6561e11..6e7d86f9c6 100644
--- a/meta/recipes-devtools/qemu/qemu_0.12.4.bb
+++ b/meta/recipes-devtools/qemu/qemu_0.12.4.bb
@@ -1,6 +1,6 @@
1require qemu.inc 1require qemu.inc
2 2
3PR = "r21" 3PR = "r22"
4 4
5FILESPATH = "${FILE_DIRNAME}/qemu-${PV}" 5FILESPATH = "${FILE_DIRNAME}/qemu-${PV}"
6FILESDIR = "${WORKDIR}" 6FILESDIR = "${WORKDIR}"
@@ -20,6 +20,7 @@ SRC_URI = "\
20 file://enable-i386-linux-user.patch \ 20 file://enable-i386-linux-user.patch \
21 file://arm-cp15-fix.patch \ 21 file://arm-cp15-fix.patch \
22 file://cursor-shadow-fix.patch \ 22 file://cursor-shadow-fix.patch \
23 file://vmware-vga-fifo-rewind.patch \
23 file://powerpc_rom.bin" 24 file://powerpc_rom.bin"
24 25
25do_install_append () { 26do_install_append () {