From: Janne Huttunen <jahuttun@gmail.com>
To: andrzej zaborowski <balrogg@gmail.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] Unknown command 0xffffff in SVGA command FIFO
Date: Wed, 21 Jul 2010 19:00:10 +0300 [thread overview]
Message-ID: <4C47198A.2080308@gmail.com> (raw)
In-Reply-To: <4C470BF2.30506@gmail.com>
> Here's an experiment for sanity checking the lengths and leaving
> the command in the FIFO if it is not complete. It fixes the
> problem for me (running it right now), but I agree that it's not
> very elegant to look at :-/ .
And here's another version with couple of stupid bugs removed
(it obviously is not a good idea to busyloop if the command is
incomplete).
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 12bff48..839f715 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -526,6 +526,17 @@ static inline int vmsvga_fifo_empty(struct vmsvga_state_s *s)
return (s->cmd->next_cmd == s->cmd->stop);
}
+static inline int vmsvga_fifo_items(struct vmsvga_state_s *s)
+{
+ int num;
+ if (!s->config || !s->enable)
+ return 0;
+ num = CMD(next_cmd) - CMD(stop);
+ if (num < 0)
+ num += (CMD(max) - CMD(min));
+ return (num >> 2);
+}
+
static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)
{
uint32_t cmd = s->fifo[CMD(stop) >> 2];
@@ -540,6 +551,14 @@ static inline uint32_t vmsvga_fifo_read(struct
vmsvga_state_s *s)
return le32_to_cpu(vmsvga_fifo_read_raw(s));
}
+static inline uint32_t vmsvga_fifo_peek(struct vmsvga_state_s *s, uint32_t offs)
+{
+ offs = (offs << 2) + CMD(stop);
+ if (offs >= CMD(max))
+ offs = offs - CMD(max) + CMD(min);
+ return le32_to_cpu(s->fifo[offs >> 2]);
+}
+
static void vmsvga_fifo_run(struct vmsvga_state_s *s)
{
uint32_t cmd, colour;
@@ -547,9 +566,12 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
int x, y, dx, dy, width, height;
struct vmsvga_cursor_definition_s cursor;
while (!vmsvga_fifo_empty(s))
- switch (cmd = vmsvga_fifo_read(s)) {
+ switch (cmd = vmsvga_fifo_peek(s, 0)) {
case SVGA_CMD_UPDATE:
case SVGA_CMD_UPDATE_VERBOSE:
+ if (vmsvga_fifo_items(s) < 5)
+ goto out;
+ vmsvga_fifo_read(s);
x = vmsvga_fifo_read(s);
y = vmsvga_fifo_read(s);
width = vmsvga_fifo_read(s);
@@ -558,6 +580,9 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
break;
case SVGA_CMD_RECT_FILL:
+ if (vmsvga_fifo_items(s) < 6)
+ goto out;
+ vmsvga_fifo_read(s);
colour = vmsvga_fifo_read(s);
x = vmsvga_fifo_read(s);
y = vmsvga_fifo_read(s);
@@ -571,6 +596,9 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
#endif
case SVGA_CMD_RECT_COPY:
+ if (vmsvga_fifo_items(s) < 7)
+ goto out;
+ vmsvga_fifo_read(s);
x = vmsvga_fifo_read(s);
y = vmsvga_fifo_read(s);
dx = vmsvga_fifo_read(s);
@@ -585,13 +613,20 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
#endif
case SVGA_CMD_DEFINE_CURSOR:
- cursor.id = vmsvga_fifo_read(s);
- cursor.hot_x = vmsvga_fifo_read(s);
- cursor.hot_y = vmsvga_fifo_read(s);
- cursor.width = x = vmsvga_fifo_read(s);
- cursor.height = y = vmsvga_fifo_read(s);
- vmsvga_fifo_read(s);
- cursor.bpp = vmsvga_fifo_read(s);
+ if (vmsvga_fifo_items(s) < 8)
+ goto out;
+ cursor.id = vmsvga_fifo_peek(s, 1);
+ cursor.hot_x = vmsvga_fifo_peek(s, 2);
+ cursor.hot_y = vmsvga_fifo_peek(s, 3);
+ cursor.width = x = vmsvga_fifo_peek(s, 4);
+ cursor.height = y = vmsvga_fifo_peek(s, 5);
+ cursor.bpp = vmsvga_fifo_peek(s, 7);
+
+ if (vmsvga_fifo_items(s) < SVGA_BITMAP_SIZE(x, y) +
SVGA_PIXMAP_SIZE(x, y, cursor.bpp) + 8)
+ goto out;
+
+ for (args = 0; args < 8; args++)
+ vmsvga_fifo_read(s);
if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
@@ -616,25 +651,43 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
* for so we can avoid FIFO desync if driver uses them illegally.
*/
case SVGA_CMD_DEFINE_ALPHA_CURSOR:
- vmsvga_fifo_read(s);
- vmsvga_fifo_read(s);
- vmsvga_fifo_read(s);
- x = vmsvga_fifo_read(s);
- y = vmsvga_fifo_read(s);
+ if (vmsvga_fifo_items(s) < 6)
+ goto out;
+ x = vmsvga_fifo_peek(s, 4);
+ y = vmsvga_fifo_peek(s, 5);
+ if (vmsvga_fifo_items(s) < x * y + 6)
+ goto out;
+ for (args = 0; args < 6; args++)
+ vmsvga_fifo_read(s);
args = x * y;
goto badcmd;
case SVGA_CMD_RECT_ROP_FILL:
+ if (vmsvga_fifo_items(s) < 7)
+ goto out;
+ vmsvga_fifo_read(s);
args = 6;
goto badcmd;
case SVGA_CMD_RECT_ROP_COPY:
+ if (vmsvga_fifo_items(s) < 8)
+ goto out;
+ vmsvga_fifo_read(s);
args = 7;
goto badcmd;
case SVGA_CMD_DRAW_GLYPH_CLIPPED:
+ if (vmsvga_fifo_items(s) < 4)
+ goto out;
+ args = 7 + (vmsvga_fifo_peek(s, 3) >> 2);
+ if (vmsvga_fifo_items(s) < args + 4)
+ goto out;
+ vmsvga_fifo_read(s);
+ vmsvga_fifo_read(s);
vmsvga_fifo_read(s);
vmsvga_fifo_read(s);
- args = 7 + (vmsvga_fifo_read(s) >> 2);
goto badcmd;
case SVGA_CMD_SURFACE_ALPHA_BLEND:
+ if (vmsvga_fifo_items(s) < 13)
+ goto out;
+ vmsvga_fifo_read(s);
args = 12;
goto badcmd;
@@ -647,6 +700,7 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
case SVGA_CMD_FRONT_ROP_FILL:
case SVGA_CMD_FENCE:
case SVGA_CMD_INVALID_CMD:
+ vmsvga_fifo_read(s);
break; /* Nop */
default:
@@ -658,6 +712,7 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
break;
}
+out:
s->syncing = 0;
}
next prev parent reply other threads:[~2010-07-21 16:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-21 11:17 [Qemu-devel] Unknown command 0xffffff in SVGA command FIFO Janne Huttunen
2010-07-21 11:45 ` andrzej zaborowski
2010-07-21 12:14 ` Janne Huttunen
2010-07-21 12:33 ` andrzej zaborowski
2010-07-21 15:02 ` Janne Huttunen
2010-07-21 16:00 ` Janne Huttunen [this message]
2010-07-23 1:35 ` balrog
2010-08-16 20:26 ` Janne Huttunen
2010-09-10 1:34 ` andrzej zaborowski
[not found] ` <4080236889252115527@unknownmsgid>
2010-07-23 1:41 ` andrzej zaborowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C47198A.2080308@gmail.com \
--to=jahuttun@gmail.com \
--cc=balrogg@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).