aboutsummaryrefslogtreecommitdiffstats
path: root/main/xen/xsa211-qemut.patch
blob: ecfc58a17a1c6cab4343b926891e0221a5be5a48 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
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 --------
 tools/qemu-xen-traditional/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/tools/qemu-xen-traditional/console.c b/tools/qemu-xen-traditional/console.c
index d4f1ad0..e61b53b 100644
--- a/tools/qemu-xen-traditional/console.c
+++ b/tools/qemu-xen-traditional/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/tools/qemu-xen-traditional/console.h b/tools/qemu-xen-traditional/console.h
index 14b42f3..8306cc4 100644
--- a/tools/qemu-xen-traditional/console.h
+++ b/tools/qemu-xen-traditional/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/tools/qemu-xen-traditional/hw/cirrus_vga.c b/tools/qemu-xen-traditional/hw/cirrus_vga.c
index 06b4a3b..4e85b90 100644
--- a/tools/qemu-xen-traditional/hw/cirrus_vga.c
+++ b/tools/qemu-xen-traditional/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/tools/qemu-xen-traditional/hw/vmware_vga.c b/tools/qemu-xen-traditional/hw/vmware_vga.c
index d1cba28..c38e43c 100644
--- a/tools/qemu-xen-traditional/hw/vmware_vga.c
+++ b/tools/qemu-xen-traditional/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/tools/qemu-xen-traditional/vnc.c b/tools/qemu-xen-traditional/vnc.c
index 61d1555..0e61197 100644
--- a/tools/qemu-xen-traditional/vnc.c
+++ b/tools/qemu-xen-traditional/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