diff options
Diffstat (limited to 'system/xen/xsa/xsa211-qemut.patch')
-rw-r--r-- | system/xen/xsa/xsa211-qemut.patch | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/system/xen/xsa/xsa211-qemut.patch b/system/xen/xsa/xsa211-qemut.patch new file mode 100644 index 0000000000..59e12fb31e --- /dev/null +++ b/system/xen/xsa/xsa211-qemut.patch @@ -0,0 +1,225 @@ +From 29e67cfd46b4d06ca1bb75558e227ec34a6af35f Mon Sep 17 00:00:00 2001 +From: Ian Jackson <ian.jackson@eu.citrix.com> +Date: Thu, 9 Mar 2017 11:14:55 +0000 +Subject: [PATCH] cirrus/vnc: zap drop bitblit support from console code. + +From: Gerd Hoffmann <kraxel@redhat.com> + +There is a special code path (dpy_gfx_copy) to allow graphic emulation +notify user interface code about bitblit operations carryed out by +guests. It is supported by cirrus and vnc server. The intended purpose +is to optimize display scrolls and just send over the scroll op instead +of a full display update. + +This is rarely used these days though because modern guests simply don't +use the cirrus blitter any more. Any linux guest using the cirrus drm +driver doesn't. Any windows guest newer than winxp doesn't ship with a +cirrus driver any more and thus uses the cirrus as simple framebuffer. + +So this code tends to bitrot and bugs can go unnoticed for a long time. +See for example commit "3e10c3e vnc: fix qemu crash because of SIGSEGV" +which fixes a bug lingering in the code for almost a year, added by +commit "c7628bf vnc: only alloc server surface with clients connected". + +Also the vnc server will throttle the frame rate in case it figures the +network can't keep up (send buffers are full). This doesn't work with +dpy_gfx_copy, for any copy operation sent to the vnc client we have to +send all outstanding updates beforehand, otherwise the vnc client might +run the client side blit on outdated data and thereby corrupt the +display. So this dpy_gfx_copy "optimization" might even make things +worse on slow network links. + +Lets kill it once for all. + +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> + +These changes (dropping dpy_copy and all its references and +implementations) reimplemented for qemu-xen-traditional. + +This is XSA-211. + +Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> +--- + console.c | 8 -------- + console.h | 16 ---------------- + hw/cirrus_vga.c | 15 +++++---------- + hw/vmware_vga.c | 1 + + vnc.c | 35 ----------------------------------- + 5 files changed, 6 insertions(+), 69 deletions(-) + +diff --git a/console.c b/console.c +index d4f1ad0..e61b53b 100644 +--- a/console.c ++++ b/console.c +@@ -1399,14 +1399,6 @@ void qemu_console_resize(DisplayState *ds, int width, int height) + } + } + +-void qemu_console_copy(DisplayState *ds, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h) +-{ +- if (is_graphic_console()) { +- dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h); +- } +-} +- + PixelFormat qemu_different_endianness_pixelformat(int bpp) + { + PixelFormat pf; +diff --git a/console.h b/console.h +index 14b42f3..8306cc4 100644 +--- a/console.h ++++ b/console.h +@@ -98,8 +98,6 @@ struct DisplayChangeListener { + void (*dpy_resize)(struct DisplayState *s); + void (*dpy_setdata)(struct DisplayState *s); + void (*dpy_refresh)(struct DisplayState *s); +- void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h); + void (*dpy_fill)(struct DisplayState *s, int x, int y, + int w, int h, uint32_t c); + void (*dpy_text_cursor)(struct DisplayState *s, int x, int y); +@@ -211,18 +209,6 @@ static inline void dpy_refresh(DisplayState *s) + } + } + +-static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h) { +- struct DisplayChangeListener *dcl = s->listeners; +- while (dcl != NULL) { +- if (dcl->dpy_copy) +- dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h); +- else /* TODO */ +- dcl->dpy_update(s, dst_x, dst_y, w, h); +- dcl = dcl->next; +- } +-} +- + static inline void dpy_fill(struct DisplayState *s, int x, int y, + int w, int h, uint32_t c) { + struct DisplayChangeListener *dcl = s->listeners; +@@ -297,8 +283,6 @@ void text_consoles_set_display(DisplayState *ds); + void console_select(unsigned int index); + void console_color_init(DisplayState *ds); + void qemu_console_resize(DisplayState *ds, int width, int height); +-void qemu_console_copy(DisplayState *ds, int src_x, int src_y, +- int dst_x, int dst_y, int w, int h); + + /* sdl.c */ + void sdl_display_init(DisplayState *ds, int full_screen, int no_frame, int opengl_enabled); +diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c +index 06b4a3b..4e85b90 100644 +--- a/hw/cirrus_vga.c ++++ b/hw/cirrus_vga.c +@@ -793,11 +793,6 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + } + } + +- /* we have to flush all pending changes so that the copy +- is generated at the appropriate moment in time */ +- if (notify) +- vga_hw_update(); +- + (*s->cirrus_rop) (s, s->vram_ptr + + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), + s->vram_ptr + +@@ -806,13 +801,13 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + s->cirrus_blt_width, s->cirrus_blt_height); + + if (notify) +- qemu_console_copy(s->ds, +- sx, sy, dx, dy, +- s->cirrus_blt_width / depth, +- s->cirrus_blt_height); ++ dpy_update(s->ds, ++ dx, dy, ++ s->cirrus_blt_width / depth, ++ s->cirrus_blt_height); + + /* we don't have to notify the display that this portion has +- changed since qemu_console_copy implies this */ ++ changed since dpy_update implies this */ + + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_width, +diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c +index d1cba28..c38e43c 100644 +--- a/hw/vmware_vga.c ++++ b/hw/vmware_vga.c +@@ -383,6 +383,7 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s, + + # ifdef DIRECT_VRAM + if (s->ds->dpy_copy) ++# error This configuration is not supported. See XSA-211. + qemu_console_copy(s->ds, x0, y0, x1, y1, w, h); + else + # endif +diff --git a/vnc.c b/vnc.c +index 61d1555..0e61197 100644 +--- a/vnc.c ++++ b/vnc.c +@@ -572,36 +572,6 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) + send_framebuffer_update_raw(vs, x, y, w, h); + } + +-static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h) +-{ +- VncState *vs = ds->opaque; +- int updating_client = 1; +- +- if (!vs->update_requested || +- src_x < vs->visible_x || src_y < vs->visible_y || +- dst_x < vs->visible_x || dst_y < vs->visible_y || +- (src_x + w) > (vs->visible_x + vs->visible_w) || +- (src_y + h) > (vs->visible_y + vs->visible_h) || +- (dst_x + w) > (vs->visible_x + vs->visible_w) || +- (dst_y + h) > (vs->visible_y + vs->visible_h)) +- updating_client = 0; +- +- if (updating_client) +- _vnc_update_client(vs); +- +- if (updating_client && vs->csock != -1 && !vs->has_update) { +- vnc_write_u8(vs, 0); /* msg id */ +- vnc_write_u8(vs, 0); +- vnc_write_u16(vs, 1); /* number of rects */ +- vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1); +- vnc_write_u16(vs, src_x); +- vnc_write_u16(vs, src_y); +- vnc_flush(vs); +- vs->update_requested--; +- } else +- framebuffer_set_updated(vs, dst_x, dst_y, w, h); +-} +- + static int find_update_height(VncState *vs, int y, int maxy, int last_x, int x) + { + int h; +@@ -1543,16 +1513,12 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) + vs->has_pointer_type_change = 0; + vs->has_WMVi = 0; + vs->absolute = -1; +- dcl->dpy_copy = NULL; + + for (i = n_encodings - 1; i >= 0; i--) { + switch (encodings[i]) { + case 0: /* Raw */ + vs->has_hextile = 0; + break; +- case 1: /* CopyRect */ +- dcl->dpy_copy = vnc_copy; +- break; + case 5: /* Hextile */ + vs->has_hextile = 1; + break; +@@ -2459,7 +2425,6 @@ static void vnc_listen_read(void *opaque) + vs->has_resize = 0; + vs->has_hextile = 0; + vs->update_requested = 0; +- dcl->dpy_copy = NULL; + vnc_timer_init(vs); + } + } +-- +2.1.4 + |