diff options
-rw-r--r-- | meta/recipes-devtools/qemu/qemu-0.12.4/vmware-vga-fifo-rewind.patch | 198 | ||||
-rw-r--r-- | meta/recipes-devtools/qemu/qemu_0.12.4.bb | 3 |
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 @@ | |||
1 | commit 4dedc07ffbbc66002e0fd2b97d5516fe6aca5eea | ||
2 | Author: Andrzej Zaborowski <balrog@zabor.org> | ||
3 | Date: 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 | |||
17 | Index: 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 @@ | |||
1 | require qemu.inc | 1 | require qemu.inc |
2 | 2 | ||
3 | PR = "r21" | 3 | PR = "r22" |
4 | 4 | ||
5 | FILESPATH = "${FILE_DIRNAME}/qemu-${PV}" | 5 | FILESPATH = "${FILE_DIRNAME}/qemu-${PV}" |
6 | FILESDIR = "${WORKDIR}" | 6 | FILESDIR = "${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 | ||
25 | do_install_append () { | 26 | do_install_append () { |