* [PATCH 1/2] ati-vga: Simplify hw cursor drawing
2026-03-08 22:49 [PATCH 0/2] Fix ati-vga segfault with guest_hwcursor=true BALATON Zoltan
@ 2026-03-08 22:49 ` BALATON Zoltan
2026-03-09 2:36 ` Chad Jablonski
2026-03-08 22:49 ` [PATCH 2/2] ati-vga: Do not access pixel outside the screen BALATON Zoltan
1 sibling, 1 reply; 5+ messages in thread
From: BALATON Zoltan @ 2026-03-08 22:49 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, marcandre.lureau, Chad Jablonski
Avoid calculating index at every step when we can just count the
position.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/display/ati.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/hw/display/ati.c b/hw/display/ati.c
index be41f2e0e2..7543065456 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -200,7 +200,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
ATIVGAState *s = container_of(vga, ATIVGAState, vga);
uint32_t srcoff;
uint32_t *dp = (uint32_t *)d;
- int i, j, h;
+ int i, j, h, idx = 0;
if (!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ||
scr_y < vga->hw_cursor_y || scr_y >= vga->hw_cursor_y + 64 ||
@@ -215,10 +215,10 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
uint32_t color;
uint8_t abits = vga_read_byte(vga, srcoff + i);
uint8_t xbits = vga_read_byte(vga, srcoff + i + 8);
- for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1) {
+ for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1, idx++) {
if (abits & BIT(7)) {
if (xbits & BIT(7)) {
- color = dp[i * 8 + j] ^ 0xffffffff; /* complement */
+ color = dp[idx] ^ 0xffffffff; /* complement */
} else {
continue; /* transparent, no change */
}
@@ -226,10 +226,10 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
color = (xbits & BIT(7) ? s->regs.cur_color1 :
s->regs.cur_color0) | 0xff000000;
}
- if (vga->hw_cursor_x + i * 8 + j >= h) {
+ if (vga->hw_cursor_x + idx >= h) {
return; /* end of screen, don't span to next line */
}
- dp[i * 8 + j] = color;
+ dp[idx] = color;
}
}
}
--
2.41.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/2] ati-vga: Do not access pixel outside the screen
2026-03-08 22:49 [PATCH 0/2] Fix ati-vga segfault with guest_hwcursor=true BALATON Zoltan
2026-03-08 22:49 ` [PATCH 1/2] ati-vga: Simplify hw cursor drawing BALATON Zoltan
@ 2026-03-08 22:49 ` BALATON Zoltan
2026-03-09 2:42 ` Chad Jablonski
1 sibling, 1 reply; 5+ messages in thread
From: BALATON Zoltan @ 2026-03-08 22:49 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, marcandre.lureau, Chad Jablonski
We check end of screen before writing the pixel but before that
complement color also accesses screen pixel so we have to check before
that. This fixes a segmentation fault with guest_hwcursor when pointer
is partially out of screen at lower right corner.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/display/ati.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 7543065456..9fb798b3e9 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -216,6 +216,9 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
uint8_t abits = vga_read_byte(vga, srcoff + i);
uint8_t xbits = vga_read_byte(vga, srcoff + i + 8);
for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1, idx++) {
+ if (vga->hw_cursor_x + idx >= h) {
+ return; /* end of screen, don't span to next line */
+ }
if (abits & BIT(7)) {
if (xbits & BIT(7)) {
color = dp[idx] ^ 0xffffffff; /* complement */
@@ -226,9 +229,6 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
color = (xbits & BIT(7) ? s->regs.cur_color1 :
s->regs.cur_color0) | 0xff000000;
}
- if (vga->hw_cursor_x + idx >= h) {
- return; /* end of screen, don't span to next line */
- }
dp[idx] = color;
}
}
--
2.41.3
^ permalink raw reply related [flat|nested] 5+ messages in thread