22d63f Switch base tarball from qemu-kvm to qemu

Authored and Committed by crobinso 12 years ago
    Switch base tarball from qemu-kvm to qemu
    
    qemu 1.3 release
    Option to use linux VFIO driver to assign PCI devices
    Many USB3 improvements
    New paravirtualized hardware random number generator device.
    Support for Glusterfs volumes with "gluster://" -drive URI
    Block job commands for live block commit and storage migration
    
        
file modified
+1 -0
.gitignore CHANGED
@@ -16,3 +16,4 @@ qemu-kvm-0.13.0-25fdf4a.tar.gz
16
16
/qemu-kvm-1.2-3e430569.tar.gz
17
17
/qemu-kvm-1.2.0-rc1.tar.gz
18
18
/qemu-kvm-1.2.0.tar.gz
19
+ /qemu-1.3.0.tar.bz2
0000-libcacard-fix-missing-symbols-in-libcacard.so.patch ADDED
@@ -0,0 +1,26 @@
1
+ From 94afb78477a5b078449e5d48b38e74aac3fa5ac4 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <94afb78477a5b078449e5d48b38e74aac3fa5ac4.1354903384.git.crobinso@redhat.com>
3
+ From: Alon Levy <alevy@redhat.com>
4
+ Date: Wed, 28 Nov 2012 16:38:43 +0200
5
+ Subject: [PATCH] libcacard: fix missing symbols in libcacard.so
6
+
7
+ ---
8
+ libcacard/Makefile | 2 +-
9
+ 1 file changed, 1 insertion(+), 1 deletion(-)
10
+
11
+ diff --git a/libcacard/Makefile b/libcacard/Makefile
12
+ index c26aac6..49a9729 100644
13
+ --- a/libcacard/Makefile
14
+ +++ b/libcacard/Makefile
15
+ @@ -7,7 +7,7 @@ libcacard_includedir=$(includedir)/cacard
16
+ $(call set-vpath, $(SRC_PATH))
17
+
18
+ # objects linked into a shared library, built with libtool with -fPIC if required
19
+ -QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o $(trace-obj-y) $(stub-obj-y)
20
+ +QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o iov.o cutils.o qemu-user.o $(trace-obj-y) $(stub-obj-y)
21
+ QEMU_OBJS_LIB=$(patsubst %.o,%.lo,$(QEMU_OBJS))
22
+
23
+ QEMU_CFLAGS+=-I../
24
+ --
25
+ 1.8.0
26
+
0001-configure-move-vscclient-binary-under-libcacard.patch ADDED
@@ -0,0 +1,96 @@
1
+ From df9d09b15cb4b8397bfe984bf3f54dbb5457d446 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <df9d09b15cb4b8397bfe984bf3f54dbb5457d446.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <94afb78477a5b078449e5d48b38e74aac3fa5ac4.1354903384.git.crobinso@redhat.com>
4
+ References: <94afb78477a5b078449e5d48b38e74aac3fa5ac4.1354903384.git.crobinso@redhat.com>
5
+ From: Alon Levy <alevy@redhat.com>
6
+ Date: Thu, 29 Nov 2012 14:11:19 +0200
7
+ Subject: [PATCH] configure: move vscclient binary under libcacard
8
+
9
+ build rule is in top level Makefile like other tools.
10
+
11
+ build rule also exists in libcacard for installation purposes. This was
12
+ fixed in a better way in 1.3.0-rc2
13
+ ---
14
+ Makefile | 4 ++--
15
+ Makefile.objs | 11 ++++++-----
16
+ configure | 2 +-
17
+ libcacard/Makefile | 6 +++++-
18
+ 4 files changed, 14 insertions(+), 9 deletions(-)
19
+
20
+ diff --git a/Makefile b/Makefile
21
+ index 9ecbcbb..c2d34a9 100644
22
+ --- a/Makefile
23
+ +++ b/Makefile
24
+ @@ -197,8 +197,8 @@ qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) libqemustub.a
25
+
26
+ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
27
+
28
+ -vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) libcacard/vscclient.o libqemustub.a
29
+ - $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@")
30
+ +libcacard/vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) iov.o cutils.o qemu-user.o libcacard/vscclient.o libqemustub.a
31
+ +libcacard/vscclient$(EXESUF): LIBS += $(libcacard_libs)
32
+
33
+ fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o oslib-posix.o $(trace-obj-y)
34
+ fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
35
+ diff --git a/Makefile.objs b/Makefile.objs
36
+ index 3c7abca..140d592 100644
37
+ --- a/Makefile.objs
38
+ +++ b/Makefile.objs
39
+ @@ -211,11 +211,12 @@ $(trace-obj-y): $(GENERATED_HEADERS)
40
+ ######################################################################
41
+ # smartcard
42
+
43
+ -libcacard-y += libcacard/cac.o libcacard/event.o
44
+ -libcacard-y += libcacard/vcard.o libcacard/vreader.o
45
+ -libcacard-y += libcacard/vcard_emul_nss.o
46
+ -libcacard-y += libcacard/vcard_emul_type.o
47
+ -libcacard-y += libcacard/card_7816.o
48
+ +libcacard-base-y += cac.o event.o
49
+ +libcacard-base-y += vcard.o vreader.o
50
+ +libcacard-base-y += vcard_emul_nss.o
51
+ +libcacard-base-y += vcard_emul_type.o
52
+ +libcacard-base-y += card_7816.o
53
+ +libcacard-y = $(addprefix libcacard/,$(libcacard-base-y))
54
+
55
+ common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y)
56
+
57
+ diff --git a/configure b/configure
58
+ index 994f731..7498e3f 100755
59
+ --- a/configure
60
+ +++ b/configure
61
+ @@ -3136,7 +3136,7 @@ if test "$softmmu" = yes ; then
62
+ fi
63
+ fi
64
+ if test "$smartcard_nss" = "yes" ; then
65
+ - tools="vscclient\$(EXESUF) $tools"
66
+ + tools="libcacard/vscclient\$(EXESUF) $tools"
67
+ fi
68
+ fi
69
+
70
+ diff --git a/libcacard/Makefile b/libcacard/Makefile
71
+ index 49a9729..750713a 100644
72
+ --- a/libcacard/Makefile
73
+ +++ b/libcacard/Makefile
74
+ @@ -47,6 +47,10 @@ libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in
75
+ < $(libcacard_srcpath)/libcacard.pc.in > libcacard.pc,\
76
+ " GEN $@")
77
+
78
+ +VSCCLIENT_QEMU_OBJS=$(addprefix ../,$(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o iov.o cutils.o qemu-user.o)
79
+ +vscclient$(EXESUF): $(VSCCLIENT_QEMU_OBJS) $(libcacard-base-y) vscclient.o
80
+ +vscclient$(EXESUF): LIBS += $(libcacard_libs)
81
+ +
82
+ .PHONY: install-libcacard
83
+
84
+ install-libcacard: libcacard.pc libcacard.la vscclient
85
+ @@ -54,7 +58,7 @@ install-libcacard: libcacard.pc libcacard.la vscclient
86
+ $(INSTALL_DIR) "$(DESTDIR)$(libdir)/pkgconfig"
87
+ $(INSTALL_DIR) "$(DESTDIR)$(libcacard_includedir)"
88
+ $(INSTALL_DIR) "$(DESTDIR)$(bindir)"
89
+ - $(LIBTOOL) --mode=install $(INSTALL_PROG) vscclient "$(DESTDIR)$(bindir)"
90
+ + $(LIBTOOL) --mode=install $(INSTALL_PROG) vscclient$(EXESUF) "$(DESTDIR)$(bindir)"
91
+ $(LIBTOOL) --mode=install $(INSTALL_DATA) libcacard.la "$(DESTDIR)$(libdir)"
92
+ $(LIBTOOL) --mode=install $(INSTALL_DATA) libcacard.pc "$(DESTDIR)$(libdir)/pkgconfig"
93
+ for inc in *.h; do \
94
+ --
95
+ 1.8.0
96
+
0002-Fix-migration-from-qemu-kvm-1.2.patch ADDED
@@ -0,0 +1,31 @@
1
+ From 633ff09ae5702676d0f33cba80db45ff5bdbde0f Mon Sep 17 00:00:00 2001
2
+ Message-Id: <633ff09ae5702676d0f33cba80db45ff5bdbde0f.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <94afb78477a5b078449e5d48b38e74aac3fa5ac4.1354903384.git.crobinso@redhat.com>
4
+ References: <94afb78477a5b078449e5d48b38e74aac3fa5ac4.1354903384.git.crobinso@redhat.com>
5
+ From: Cole Robinson <crobinso@redhat.com>
6
+ Date: Fri, 7 Dec 2012 12:32:41 -0500
7
+ Subject: [PATCH] Fix migration from qemu-kvm 1.2
8
+
9
+ As suggested by Marcelo
10
+ ---
11
+ hw/acpi_piix4.c | 4 ++--
12
+ 1 file changed, 2 insertions(+), 2 deletions(-)
13
+
14
+ diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
15
+ index 519269a..66adc88 100644
16
+ --- a/hw/acpi_piix4.c
17
+ +++ b/hw/acpi_piix4.c
18
+ @@ -310,8 +310,8 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
19
+ */
20
+ static const VMStateDescription vmstate_acpi = {
21
+ .name = "piix4_pm",
22
+ - .version_id = 3,
23
+ - .minimum_version_id = 3,
24
+ + .version_id = 2,
25
+ + .minimum_version_id = 2,
26
+ .minimum_version_id_old = 1,
27
+ .load_state_old = acpi_load_old,
28
+ .post_load = vmstate_acpi_post_load,
29
+ --
30
+ 1.8.0
31
+
0100-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch ADDED
@@ -0,0 +1,58 @@
1
+ From 9f0944a25bc1094fa7a74ac9df14e184e2c5c82d Mon Sep 17 00:00:00 2001
2
+ Message-Id: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
3
+ From: Amit Shah <amit.shah@redhat.com>
4
+ Date: Mon, 21 Mar 2011 21:57:47 +0100
5
+ Subject: [PATCH] char: Split out tcp socket close code in a separate function
6
+
7
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
8
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
9
+ ---
10
+ qemu-char.c | 25 ++++++++++++++++---------
11
+ 1 file changed, 16 insertions(+), 9 deletions(-)
12
+
13
+ diff --git a/qemu-char.c b/qemu-char.c
14
+ index 242b799..77776dc 100644
15
+ --- a/qemu-char.c
16
+ +++ b/qemu-char.c
17
+ @@ -2146,6 +2146,21 @@ typedef struct {
18
+
19
+ static void tcp_chr_accept(void *opaque);
20
+
21
+ +static void tcp_closed(void *opaque)
22
+ +{
23
+ + CharDriverState *chr = opaque;
24
+ + TCPCharDriver *s = chr->opaque;
25
+ +
26
+ + s->connected = 0;
27
+ + if (s->listen_fd >= 0) {
28
+ + qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
29
+ + }
30
+ + qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
31
+ + closesocket(s->fd);
32
+ + s->fd = -1;
33
+ + qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
34
+ +}
35
+ +
36
+ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
37
+ {
38
+ TCPCharDriver *s = chr->opaque;
39
+ @@ -2304,15 +2319,7 @@ static void tcp_chr_read(void *opaque)
40
+ len = s->max_size;
41
+ size = tcp_chr_recv(chr, (void *)buf, len);
42
+ if (size == 0) {
43
+ - /* connection closed */
44
+ - s->connected = 0;
45
+ - if (s->listen_fd >= 0) {
46
+ - qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
47
+ - }
48
+ - qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
49
+ - closesocket(s->fd);
50
+ - s->fd = -1;
51
+ - qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
52
+ + tcp_closed(chr);
53
+ } else if (size > 0) {
54
+ if (s->do_telnetopt)
55
+ tcp_chr_process_IAC_bytes(chr, s, buf, &size);
56
+ --
57
+ 1.8.0
58
+
0101-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch ADDED
@@ -0,0 +1,1046 @@
1
+ From 501ffec04b2b5104ef854624027f0cd769d5d314 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <501ffec04b2b5104ef854624027f0cd769d5d314.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Mon, 21 Mar 2011 20:31:45 +0100
7
+ Subject: [PATCH] char: Add a QemuChrHandlers struct to initialise chardev
8
+ handlers
9
+
10
+ Instead of passing each handler in the qemu_add_handlers() function,
11
+ create a struct of handlers that can be passed to the function instead.
12
+
13
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
14
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
15
+ ---
16
+ backends/rng-egd.c | 12 +++++++++---
17
+ gdbstub.c | 9 +++++++--
18
+ hw/cadence_uart.c | 9 +++++++--
19
+ hw/ccid-card-passthru.c | 11 +++++++----
20
+ hw/debugcon.c | 2 +-
21
+ hw/escc.c | 9 +++++++--
22
+ hw/etraxfs_ser.c | 13 +++++++++----
23
+ hw/exynos4210_uart.c | 9 +++++++--
24
+ hw/grlib_apbuart.c | 12 +++++++-----
25
+ hw/imx_serial.c | 9 +++++++--
26
+ hw/ivshmem.c | 28 ++++++++++++++++++++++------
27
+ hw/lm32_juart.c | 8 +++++++-
28
+ hw/lm32_uart.c | 8 +++++++-
29
+ hw/mcf_uart.c | 9 +++++++--
30
+ hw/milkymist-uart.c | 8 +++++++-
31
+ hw/pl011.c | 9 +++++++--
32
+ hw/pxa2xx.c | 13 +++++++++----
33
+ hw/qdev-properties.c | 2 +-
34
+ hw/s390x/sclpconsole.c | 9 +++++++--
35
+ hw/serial.c | 11 ++++++++---
36
+ hw/sh_serial.c | 12 +++++++++---
37
+ hw/spapr_vty.c | 8 ++++++--
38
+ hw/strongarm.c | 12 +++++++-----
39
+ hw/usb/dev-serial.c | 11 ++++++++---
40
+ hw/usb/redirect.c | 9 +++++++--
41
+ hw/virtio-console.c | 9 +++++++--
42
+ hw/xen_console.c | 16 +++++++++++-----
43
+ hw/xilinx_uartlite.c | 11 +++++++++--
44
+ monitor.c | 18 ++++++++++++++----
45
+ net/slirp.c | 8 ++++++--
46
+ qemu-char.c | 32 ++++++++++++++++++++++----------
47
+ qemu-char.h | 13 +++++++++----
48
+ qtest.c | 9 ++++++++-
49
+ 33 files changed, 273 insertions(+), 95 deletions(-)
50
+
51
+ diff --git a/backends/rng-egd.c b/backends/rng-egd.c
52
+ index ad84737..30194be 100644
53
+ --- a/backends/rng-egd.c
54
+ +++ b/backends/rng-egd.c
55
+ @@ -133,6 +133,13 @@ static void rng_egd_cancel_requests(RngBackend *b)
56
+ rng_egd_free_requests(s);
57
+ }
58
+
59
+ +static const QemuChrHandlers rng_egd_handlers = {
60
+ + .fd_can_read = rng_egd_chr_can_read,
61
+ + .fd_read = rng_egd_chr_read,
62
+ + .fd_event = NULL,
63
+ +};
64
+ +
65
+ +
66
+ static void rng_egd_opened(RngBackend *b, Error **errp)
67
+ {
68
+ RngEgd *s = RNG_EGD(b);
69
+ @@ -150,8 +157,7 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
70
+ }
71
+
72
+ /* FIXME we should resubmit pending requests when the CDS reconnects. */
73
+ - qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read,
74
+ - NULL, s);
75
+ + qemu_chr_add_handlers(s->chr, &rng_egd_handlers, s);
76
+ }
77
+
78
+ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
79
+ @@ -190,7 +196,7 @@ static void rng_egd_finalize(Object *obj)
80
+ RngEgd *s = RNG_EGD(obj);
81
+
82
+ if (s->chr) {
83
+ - qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
84
+ + qemu_chr_add_handlers(s->chr, NULL, NULL);
85
+ }
86
+
87
+ g_free(s->chr_name);
88
+ diff --git a/gdbstub.c b/gdbstub.c
89
+ index d02ec75..5d93d20 100644
90
+ --- a/gdbstub.c
91
+ +++ b/gdbstub.c
92
+ @@ -2973,6 +2973,12 @@ static void gdb_sigterm_handler(int signal)
93
+ }
94
+ #endif
95
+
96
+ +static const QemuChrHandlers gdb_handlers = {
97
+ + .fd_can_read = gdb_chr_can_receive,
98
+ + .fd_read = gdb_chr_receive,
99
+ + .fd_event = gdb_chr_event,
100
+ +};
101
+ +
102
+ int gdbserver_start(const char *device)
103
+ {
104
+ GDBState *s;
105
+ @@ -3002,8 +3008,7 @@ int gdbserver_start(const char *device)
106
+ if (!chr)
107
+ return -1;
108
+
109
+ - qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
110
+ - gdb_chr_event, NULL);
111
+ + qemu_chr_add_handlers(chr, &gdb_handlers, NULL);
112
+ }
113
+
114
+ s = gdbserver_state;
115
+ diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c
116
+ index 686e617..36ad620 100644
117
+ --- a/hw/cadence_uart.c
118
+ +++ b/hw/cadence_uart.c
119
+ @@ -438,6 +438,12 @@ static void cadence_uart_reset(UartState *s)
120
+ s->rx_wpos = 0;
121
+ }
122
+
123
+ +static const QemuChrHandlers cadence_uart_handlers = {
124
+ + .fd_can_read = uart_can_receive,
125
+ + .fd_read = uart_receive,
126
+ + .fd_event = uart_event,
127
+ +};
128
+ +
129
+ static int cadence_uart_init(SysBusDevice *dev)
130
+ {
131
+ UartState *s = FROM_SYSBUS(UartState, dev);
132
+ @@ -459,8 +465,7 @@ static int cadence_uart_init(SysBusDevice *dev)
133
+ cadence_uart_reset(s);
134
+
135
+ if (s->chr) {
136
+ - qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive,
137
+ - uart_event, s);
138
+ + qemu_chr_add_handlers(s->chr, &cadence_uart_handlers, s);
139
+ }
140
+
141
+ return 0;
142
+ diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
143
+ index bd6c777..fb32107 100644
144
+ --- a/hw/ccid-card-passthru.c
145
+ +++ b/hw/ccid-card-passthru.c
146
+ @@ -274,6 +274,12 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
147
+ return card->atr;
148
+ }
149
+
150
+ +static const QemuChrHandlers passthru_handlers = {
151
+ + .fd_can_read = ccid_card_vscard_can_read,
152
+ + .fd_read = ccid_card_vscard_read,
153
+ + .fd_event = ccid_card_vscard_event,
154
+ +};
155
+ +
156
+ static int passthru_initfn(CCIDCardState *base)
157
+ {
158
+ PassthruState *card = DO_UPCAST(PassthruState, base, base);
159
+ @@ -282,10 +288,7 @@ static int passthru_initfn(CCIDCardState *base)
160
+ card->vscard_in_hdr = 0;
161
+ if (card->cs) {
162
+ DPRINTF(card, D_INFO, "initing chardev\n");
163
+ - qemu_chr_add_handlers(card->cs,
164
+ - ccid_card_vscard_can_read,
165
+ - ccid_card_vscard_read,
166
+ - ccid_card_vscard_event, card);
167
+ + qemu_chr_add_handlers(card->cs, &passthru_handlers, card);
168
+ ccid_card_vscard_send_init(card);
169
+ } else {
170
+ error_report("missing chardev");
171
+ diff --git a/hw/debugcon.c b/hw/debugcon.c
172
+ index 14ab326..7887fd2 100644
173
+ --- a/hw/debugcon.c
174
+ +++ b/hw/debugcon.c
175
+ @@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s)
176
+ exit(1);
177
+ }
178
+
179
+ - qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
180
+ + qemu_chr_add_handlers(s->chr, NULL, s);
181
+ }
182
+
183
+ static int debugcon_isa_initfn(ISADevice *dev)
184
+ diff --git a/hw/escc.c b/hw/escc.c
185
+ index a356613..3f26f45 100644
186
+ --- a/hw/escc.c
187
+ +++ b/hw/escc.c
188
+ @@ -867,6 +867,12 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
189
+ sysbus_mmio_map(s, 0, base);
190
+ }
191
+
192
+ +static const QemuChrHandlers serial_handlers = {
193
+ + .fd_can_read = serial_can_receive,
194
+ + .fd_read = serial_receive1,
195
+ + .fd_event = serial_event,
196
+ +};
197
+ +
198
+ static int escc_init1(SysBusDevice *dev)
199
+ {
200
+ SerialState *s = FROM_SYSBUS(SerialState, dev);
201
+ @@ -879,8 +885,7 @@ static int escc_init1(SysBusDevice *dev)
202
+ s->chn[i].chn = 1 - i;
203
+ s->chn[i].clock = s->frequency / 2;
204
+ if (s->chn[i].chr) {
205
+ - qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
206
+ - serial_receive1, serial_event, &s->chn[i]);
207
+ + qemu_chr_add_handlers(s->chn[i].chr, &serial_handlers, &s->chn[i]);
208
+ }
209
+ }
210
+ s->chn[0].otherchn = &s->chn[1];
211
+ diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
212
+ index ee0d72b..64552cc 100644
213
+ --- a/hw/etraxfs_ser.c
214
+ +++ b/hw/etraxfs_ser.c
215
+ @@ -208,6 +208,12 @@ static void etraxfs_ser_reset(DeviceState *d)
216
+
217
+ }
218
+
219
+ +static const QemuChrHandlers serial_handlers = {
220
+ + .fd_can_read = serial_can_receive,
221
+ + .fd_read = serial_receive,
222
+ + .fd_event = serial_event,
223
+ +};
224
+ +
225
+ static int etraxfs_ser_init(SysBusDevice *dev)
226
+ {
227
+ struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
228
+ @@ -217,10 +223,9 @@ static int etraxfs_ser_init(SysBusDevice *dev)
229
+ sysbus_init_mmio(dev, &s->mmio);
230
+
231
+ s->chr = qemu_char_get_next_serial();
232
+ - if (s->chr)
233
+ - qemu_chr_add_handlers(s->chr,
234
+ - serial_can_receive, serial_receive,
235
+ - serial_event, s);
236
+ + if (s->chr) {
237
+ + qemu_chr_add_handlers(s->chr, &serial_handlers, s);
238
+ + }
239
+ return 0;
240
+ }
241
+
242
+ diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
243
+ index 20dcd9f..f2949aa 100644
244
+ --- a/hw/exynos4210_uart.c
245
+ +++ b/hw/exynos4210_uart.c
246
+ @@ -625,6 +625,12 @@ DeviceState *exynos4210_uart_create(hwaddr addr,
247
+ return dev;
248
+ }
249
+
250
+ +static const QemuChrHandlers exynos4210_handlers = {
251
+ + .fd_can_read = exynos4210_uart_can_receive,
252
+ + .fd_read = exynos4210_uart_receive,
253
+ + .fd_event = exynos4210_uart_event,
254
+ +};
255
+ +
256
+ static int exynos4210_uart_init(SysBusDevice *dev)
257
+ {
258
+ Exynos4210UartState *s = FROM_SYSBUS(Exynos4210UartState, dev);
259
+ @@ -636,8 +642,7 @@ static int exynos4210_uart_init(SysBusDevice *dev)
260
+
261
+ sysbus_init_irq(dev, &s->irq);
262
+
263
+ - qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive,
264
+ - exynos4210_uart_receive, exynos4210_uart_event, s);
265
+ + qemu_chr_add_handlers(s->chr, &exynos4210_handlers, s);
266
+
267
+ return 0;
268
+ }
269
+ diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
270
+ index 0865764..fb0e703 100644
271
+ --- a/hw/grlib_apbuart.c
272
+ +++ b/hw/grlib_apbuart.c
273
+ @@ -222,15 +222,17 @@ static const MemoryRegionOps grlib_apbuart_ops = {
274
+ .endianness = DEVICE_NATIVE_ENDIAN,
275
+ };
276
+
277
+ +static const QemuChrHandlers grlib_handlers = {
278
+ + .fd_can_read = grlib_apbuart_can_receive,
279
+ + .fd_read = grlib_apbuart_receive,
280
+ + .fd_event = grlib_apbuart_event,
281
+ +};
282
+ +
283
+ static int grlib_apbuart_init(SysBusDevice *dev)
284
+ {
285
+ UART *uart = FROM_SYSBUS(typeof(*uart), dev);
286
+
287
+ - qemu_chr_add_handlers(uart->chr,
288
+ - grlib_apbuart_can_receive,
289
+ - grlib_apbuart_receive,
290
+ - grlib_apbuart_event,
291
+ - uart);
292
+ + qemu_chr_add_handlers(uart->chr, &grlib_handlers, uart);
293
+
294
+ sysbus_init_irq(dev, &uart->irq);
295
+
296
+ diff --git a/hw/imx_serial.c b/hw/imx_serial.c
297
+ index dcd125f..5347ec8 100644
298
+ --- a/hw/imx_serial.c
299
+ +++ b/hw/imx_serial.c
300
+ @@ -381,6 +381,12 @@ static const struct MemoryRegionOps imx_serial_ops = {
301
+ .endianness = DEVICE_NATIVE_ENDIAN,
302
+ };
303
+
304
+ +static const QemuChrHandlers imx_handlers = {
305
+ + .fd_can_read = imx_can_receive,
306
+ + .fd_read = imx_receive,
307
+ + .fd_event = imx_event,
308
+ +};
309
+ +
310
+ static int imx_serial_init(SysBusDevice *dev)
311
+ {
312
+ IMXSerialState *s = FROM_SYSBUS(IMXSerialState, dev);
313
+ @@ -391,8 +397,7 @@ static int imx_serial_init(SysBusDevice *dev)
314
+ sysbus_init_irq(dev, &s->irq);
315
+
316
+ if (s->chr) {
317
+ - qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
318
+ - imx_event, s);
319
+ + qemu_chr_add_handlers(s->chr, &imx_handlers, s);
320
+ } else {
321
+ DPRINTF("No char dev for uart at 0x%lx\n",
322
+ (unsigned long)s->iomem.ram_addr);
323
+ diff --git a/hw/ivshmem.c b/hw/ivshmem.c
324
+ index f6dbb21..0e56a97 100644
325
+ --- a/hw/ivshmem.c
326
+ +++ b/hw/ivshmem.c
327
+ @@ -274,6 +274,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) {
328
+ msix_notify(pdev, entry->vector);
329
+ }
330
+
331
+ +static const QemuChrHandlers ivshmem_handlers = {
332
+ + .fd_can_read = ivshmem_can_receive,
333
+ + .fd_read = ivshmem_receive,
334
+ + .fd_event = ivshmem_event,
335
+ +};
336
+ +
337
+ +static const QemuChrHandlers ivshmem_msi_handlers = {
338
+ + .fd_can_read = ivshmem_can_receive,
339
+ + .fd_read = fake_irqfd,
340
+ + .fd_event = ivshmem_event,
341
+ +};
342
+ +
343
+ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *n,
344
+ int vector)
345
+ {
346
+ @@ -294,11 +306,10 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *
347
+ s->eventfd_table[vector].pdev = &s->dev;
348
+ s->eventfd_table[vector].vector = vector;
349
+
350
+ - qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd,
351
+ - ivshmem_event, &s->eventfd_table[vector]);
352
+ + qemu_chr_add_handlers(chr, &ivshmem_msi_handlers,
353
+ + &s->eventfd_table[vector]);
354
+ } else {
355
+ - qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive,
356
+ - ivshmem_event, s);
357
+ + qemu_chr_add_handlers(chr, &ivshmem_handlers, s);
358
+ }
359
+
360
+ return chr;
361
+ @@ -632,6 +643,12 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
362
+ msix_write_config(pci_dev, address, val, len);
363
+ }
364
+
365
+ +static const QemuChrHandlers ivshmem_server_handlers = {
366
+ + .fd_can_read = ivshmem_can_receive,
367
+ + .fd_read = ivshmem_read,
368
+ + .fd_event = ivshmem_event,
369
+ +};
370
+ +
371
+ static int pci_ivshmem_init(PCIDevice *dev)
372
+ {
373
+ IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
374
+ @@ -722,8 +739,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
375
+
376
+ s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));
377
+
378
+ - qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read,
379
+ - ivshmem_event, s);
380
+ + qemu_chr_add_handlers(s->server_chr, &ivshmem_server_handlers, s);
381
+ } else {
382
+ /* just map the file immediately, we're not using a server */
383
+ int fd;
384
+ diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
385
+ index f07ed39..d4daeb8 100644
386
+ --- a/hw/lm32_juart.c
387
+ +++ b/hw/lm32_juart.c
388
+ @@ -110,13 +110,19 @@ static void juart_reset(DeviceState *d)
389
+ s->jrx = 0;
390
+ }
391
+
392
+ +static const QemuChrHandlers juart_handlers = {
393
+ + .fd_can_read = juart_can_rx,
394
+ + .fd_read = juart_rx,
395
+ + .fd_event = juart_event,
396
+ +};
397
+ +
398
+ static int lm32_juart_init(SysBusDevice *dev)
399
+ {
400
+ LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev);
401
+
402
+ s->chr = qemu_char_get_next_serial();
403
+ if (s->chr) {
404
+ - qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
405
+ + qemu_chr_add_handlers(s->chr, &juart_handlers, s);
406
+ }
407
+
408
+ return 0;
409
+ diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
410
+ index adb9287..e581bea 100644
411
+ --- a/hw/lm32_uart.c
412
+ +++ b/hw/lm32_uart.c
413
+ @@ -243,6 +243,12 @@ static void uart_reset(DeviceState *d)
414
+ s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
415
+ }
416
+
417
+ +static const QemuChrHandlers uart_handlers = {
418
+ + .fd_can_read = uart_can_rx,
419
+ + .fd_read = uart_rx,
420
+ + .fd_event = uart_event,
421
+ +};
422
+ +
423
+ static int lm32_uart_init(SysBusDevice *dev)
424
+ {
425
+ LM32UartState *s = FROM_SYSBUS(typeof(*s), dev);
426
+ @@ -254,7 +260,7 @@ static int lm32_uart_init(SysBusDevice *dev)
427
+
428
+ s->chr = qemu_char_get_next_serial();
429
+ if (s->chr) {
430
+ - qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
431
+ + qemu_chr_add_handlers(s->chr, &uart_handlers, s);
432
+ }
433
+
434
+ return 0;
435
+ diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
436
+ index d1655f8..8ead254 100644
437
+ --- a/hw/mcf_uart.c
438
+ +++ b/hw/mcf_uart.c
439
+ @@ -272,6 +272,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
440
+ mcf_uart_push_byte(s, buf[0]);
441
+ }
442
+
443
+ +static const QemuChrHandlers mcf_uart_handlers = {
444
+ + .fd_can_read = mcf_uart_can_receive,
445
+ + .fd_read = mcf_uart_receive,
446
+ + .fd_event = mcf_uart_event,
447
+ +};
448
+ +
449
+ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
450
+ {
451
+ mcf_uart_state *s;
452
+ @@ -280,8 +286,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
453
+ s->chr = chr;
454
+ s->irq = irq;
455
+ if (chr) {
456
+ - qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
457
+ - mcf_uart_event, s);
458
+ + qemu_chr_add_handlers(chr, &mcf_uart_handlers, s);
459
+ }
460
+ mcf_uart_reset(s);
461
+ return s;
462
+ diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
463
+ index aefa8c7..0c924f2 100644
464
+ --- a/hw/milkymist-uart.c
465
+ +++ b/hw/milkymist-uart.c
466
+ @@ -189,6 +189,12 @@ static void milkymist_uart_reset(DeviceState *d)
467
+ s->regs[R_STAT] = STAT_THRE;
468
+ }
469
+
470
+ +static const QemuChrHandlers uart_handlers = {
471
+ + .fd_can_read = uart_can_rx,
472
+ + .fd_read = uart_rx,
473
+ + .fd_event = uart_event,
474
+ +};
475
+ +
476
+ static int milkymist_uart_init(SysBusDevice *dev)
477
+ {
478
+ MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev);
479
+ @@ -201,7 +207,7 @@ static int milkymist_uart_init(SysBusDevice *dev)
480
+
481
+ s->chr = qemu_char_get_next_serial();
482
+ if (s->chr) {
483
+ - qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
484
+ + qemu_chr_add_handlers(s->chr, &uart_handlers, s);
485
+ }
486
+
487
+ return 0;
488
+ diff --git a/hw/pl011.c b/hw/pl011.c
489
+ index 1f7ce2f..7f44c55 100644
490
+ --- a/hw/pl011.c
491
+ +++ b/hw/pl011.c
492
+ @@ -261,6 +261,12 @@ static const VMStateDescription vmstate_pl011 = {
493
+ }
494
+ };
495
+
496
+ +static const QemuChrHandlers pl011_handlers = {
497
+ + .fd_can_read = pl011_can_receive,
498
+ + .fd_read = pl011_receive,
499
+ + .fd_event = pl011_event,
500
+ +};
501
+ +
502
+ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
503
+ {
504
+ pl011_state *s = FROM_SYSBUS(pl011_state, dev);
505
+ @@ -276,8 +282,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
506
+ s->cr = 0x300;
507
+ s->flags = 0x90;
508
+ if (s->chr) {
509
+ - qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
510
+ - pl011_event, s);
511
+ + qemu_chr_add_handlers(s->chr, &pl011_handlers, s);
512
+ }
513
+ vmstate_register(&dev->qdev, -1, &vmstate_pl011, s);
514
+ return 0;
515
+ diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
516
+ index e616979..f9ca062 100644
517
+ --- a/hw/pxa2xx.c
518
+ +++ b/hw/pxa2xx.c
519
+ @@ -1962,6 +1962,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id)
520
+ return 0;
521
+ }
522
+
523
+ +static const QemuChrHandlers pxa2xx_handlers = {
524
+ + .fd_can_read = pxa2xx_fir_is_empty,
525
+ + .fd_read = pxa2xx_fir_rx,
526
+ + .fd_event = pxa2xx_fir_event,
527
+ +};
528
+ +
529
+ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
530
+ hwaddr base,
531
+ qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma,
532
+ @@ -1980,10 +1986,9 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
533
+ memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000);
534
+ memory_region_add_subregion(sysmem, base, &s->iomem);
535
+
536
+ - if (chr)
537
+ - qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
538
+ - pxa2xx_fir_rx, pxa2xx_fir_event, s);
539
+ -
540
+ + if (chr) {
541
+ + qemu_chr_add_handlers(chr, &pxa2xx_handlers, s);
542
+ + }
543
+ register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
544
+ pxa2xx_fir_load, s);
545
+
546
+ diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
547
+ index 81d901c..9e2b893 100644
548
+ --- a/hw/qdev-properties.c
549
+ +++ b/hw/qdev-properties.c
550
+ @@ -550,7 +550,7 @@ static void release_chr(Object *obj, const char *name, void *opaque)
551
+ CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
552
+
553
+ if (*ptr) {
554
+ - qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
555
+ + qemu_chr_add_handlers(*ptr, NULL, NULL);
556
+ }
557
+ }
558
+
559
+ diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
560
+ index 0ec5623..b3d1d6b 100644
561
+ --- a/hw/s390x/sclpconsole.c
562
+ +++ b/hw/s390x/sclpconsole.c
563
+ @@ -240,6 +240,12 @@ static void trigger_ascii_console_data(void *env, int n, int level)
564
+ sclp_service_interrupt(0);
565
+ }
566
+
567
+ +static const QemuChrHandlers sclp_chr_handlers = {
568
+ + .fd_can_read = chr_can_read,
569
+ + .fd_read = chr_read,
570
+ + .fd_event = chr_event,
571
+ +};
572
+ +
573
+ /* qemu object creation and initialization functions */
574
+
575
+ /* tell character layer our call-back functions */
576
+ @@ -256,8 +262,7 @@ static int console_init(SCLPEvent *event)
577
+ console_available = true;
578
+ event->event_type = SCLP_EVENT_ASCII_CONSOLE_DATA;
579
+ if (scon->chr) {
580
+ - qemu_chr_add_handlers(scon->chr, chr_can_read,
581
+ - chr_read, chr_event, scon);
582
+ + qemu_chr_add_handlers(scon->chr, &sclp_chr_handlers, scon);
583
+ }
584
+ scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data,
585
+ NULL, 1);
586
+ diff --git a/hw/serial.c b/hw/serial.c
587
+ index 60283ea..9134d01 100644
588
+ --- a/hw/serial.c
589
+ +++ b/hw/serial.c
590
+ @@ -676,6 +676,12 @@ static void serial_reset(void *opaque)
591
+ qemu_irq_lower(s->irq);
592
+ }
593
+
594
+ +static const QemuChrHandlers serial_handlers = {
595
+ + .fd_can_read = serial_can_receive1,
596
+ + .fd_read = serial_receive1,
597
+ + .fd_event = serial_event,
598
+ +};
599
+ +
600
+ void serial_init_core(SerialState *s)
601
+ {
602
+ if (!s->chr) {
603
+ @@ -690,13 +696,12 @@ void serial_init_core(SerialState *s)
604
+
605
+ qemu_register_reset(serial_reset, s);
606
+
607
+ - qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
608
+ - serial_event, s);
609
+ + qemu_chr_add_handlers(s->chr, &serial_handlers, s);
610
+ }
611
+
612
+ void serial_exit_core(SerialState *s)
613
+ {
614
+ - qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
615
+ + qemu_chr_add_handlers(s->chr, NULL, NULL);
616
+ qemu_unregister_reset(serial_reset, s);
617
+ }
618
+
619
+ diff --git a/hw/sh_serial.c b/hw/sh_serial.c
620
+ index 9da5d08..260185d 100644
621
+ --- a/hw/sh_serial.c
622
+ +++ b/hw/sh_serial.c
623
+ @@ -352,6 +352,12 @@ static const MemoryRegionOps sh_serial_ops = {
624
+ .endianness = DEVICE_NATIVE_ENDIAN,
625
+ };
626
+
627
+ +static const QemuChrHandlers sh_serial_handlers = {
628
+ + .fd_can_read = sh_serial_can_receive1,
629
+ + .fd_read = sh_serial_receive1,
630
+ + .fd_event = sh_serial_event,
631
+ +};
632
+ +
633
+ void sh_serial_init(MemoryRegion *sysmem,
634
+ hwaddr base, int feat,
635
+ uint32_t freq, CharDriverState *chr,
636
+ @@ -396,9 +402,9 @@ void sh_serial_init(MemoryRegion *sysmem,
637
+
638
+ s->chr = chr;
639
+
640
+ - if (chr)
641
+ - qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
642
+ - sh_serial_event, s);
643
+ + if (chr) {
644
+ + qemu_chr_add_handlers(chr, &sh_serial_handlers, s);
645
+ + }
646
+
647
+ s->eri = eri_source;
648
+ s->rxi = rxi_source;
649
+ diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
650
+ index 14f862f..9fbe7dd 100644
651
+ --- a/hw/spapr_vty.c
652
+ +++ b/hw/spapr_vty.c
653
+ @@ -54,6 +54,11 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
654
+ qemu_chr_fe_write(dev->chardev, buf, len);
655
+ }
656
+
657
+ +static const QemuChrHandlers vty_handlers = {
658
+ + .fd_can_read = vty_can_receive,
659
+ + .fd_read = vty_receive,
660
+ +};
661
+ +
662
+ static int spapr_vty_init(VIOsPAPRDevice *sdev)
663
+ {
664
+ VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
665
+ @@ -63,8 +68,7 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
666
+ exit(1);
667
+ }
668
+
669
+ - qemu_chr_add_handlers(dev->chardev, vty_can_receive,
670
+ - vty_receive, NULL, dev);
671
+ + qemu_chr_add_handlers(dev->chardev, &vty_handlers, dev);
672
+
673
+ return 0;
674
+ }
675
+ diff --git a/hw/strongarm.c b/hw/strongarm.c
676
+ index 4385515..3567218 100644
677
+ --- a/hw/strongarm.c
678
+ +++ b/hw/strongarm.c
679
+ @@ -1199,6 +1199,12 @@ static const MemoryRegionOps strongarm_uart_ops = {
680
+ .endianness = DEVICE_NATIVE_ENDIAN,
681
+ };
682
+
683
+ +static const QemuChrHandlers strongarm_uart_handlers = {
684
+ + .fd_can_read = strongarm_uart_can_receive,
685
+ + .fd_read = strongarm_uart_receive,
686
+ + .fd_event = strongarm_uart_event,
687
+ +};
688
+ +
689
+ static int strongarm_uart_init(SysBusDevice *dev)
690
+ {
691
+ StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev);
692
+ @@ -1211,11 +1217,7 @@ static int strongarm_uart_init(SysBusDevice *dev)
693
+ s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
694
+
695
+ if (s->chr) {
696
+ - qemu_chr_add_handlers(s->chr,
697
+ - strongarm_uart_can_receive,
698
+ - strongarm_uart_receive,
699
+ - strongarm_uart_event,
700
+ - s);
701
+ + qemu_chr_add_handlers(s->chr, &strongarm_uart_handlers, s);
702
+ }
703
+
704
+ return 0;
705
+ diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
706
+ index 99b19df..7307ad2 100644
707
+ --- a/hw/usb/dev-serial.c
708
+ +++ b/hw/usb/dev-serial.c
709
+ @@ -414,7 +414,7 @@ static void usb_serial_handle_destroy(USBDevice *dev)
710
+ {
711
+ USBSerialState *s = (USBSerialState *)dev;
712
+
713
+ - qemu_chr_add_handlers(s->cs, NULL, NULL, NULL, NULL);
714
+ + qemu_chr_add_handlers(s->cs, NULL, NULL);
715
+ }
716
+
717
+ static int usb_serial_can_read(void *opaque)
718
+ @@ -478,6 +478,12 @@ static void usb_serial_event(void *opaque, int event)
719
+ }
720
+ }
721
+
722
+ +static const QemuChrHandlers usb_serial_handlers = {
723
+ + .fd_can_read = usb_serial_can_read,
724
+ + .fd_read = usb_serial_read,
725
+ + .fd_event = usb_serial_event,
726
+ +};
727
+ +
728
+ static int usb_serial_initfn(USBDevice *dev)
729
+ {
730
+ USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev);
731
+ @@ -491,8 +497,7 @@ static int usb_serial_initfn(USBDevice *dev)
732
+ return -1;
733
+ }
734
+
735
+ - qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
736
+ - usb_serial_event, s);
737
+ + qemu_chr_add_handlers(s->cs, &usb_serial_handlers, s);
738
+ usb_serial_handle_reset(dev);
739
+
740
+ if (s->cs->opened && !dev->attached) {
741
+ diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
742
+ index 490c90f..c921d2d 100644
743
+ --- a/hw/usb/redirect.c
744
+ +++ b/hw/usb/redirect.c
745
+ @@ -1037,6 +1037,12 @@ static void usbredir_chardev_event(void *opaque, int event)
746
+ }
747
+ }
748
+
749
+ +static const QemuChrHandlers usbredir_chr_handlers = {
750
+ + .fd_can_read = usbredir_chardev_can_read,
751
+ + .fd_read = usbredir_chardev_read,
752
+ + .fd_event = usbredir_chardev_event,
753
+ +};
754
+ +
755
+ /*
756
+ * init + destroy
757
+ */
758
+ @@ -1088,8 +1094,7 @@ static int usbredir_initfn(USBDevice *udev)
759
+
760
+ /* Let the backend know we are ready */
761
+ qemu_chr_fe_open(dev->cs);
762
+ - qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
763
+ - usbredir_chardev_read, usbredir_chardev_event, dev);
764
+ + qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
765
+
766
+ qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
767
+ add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
768
+ diff --git a/hw/virtio-console.c b/hw/virtio-console.c
769
+ index cffee3d..066590c 100644
770
+ --- a/hw/virtio-console.c
771
+ +++ b/hw/virtio-console.c
772
+ @@ -106,6 +106,12 @@ static void chr_event(void *opaque, int event)
773
+ }
774
+ }
775
+
776
+ +static const QemuChrHandlers chr_handlers = {
777
+ + .fd_can_read = chr_can_read,
778
+ + .fd_read = chr_read,
779
+ + .fd_event = chr_event,
780
+ +};
781
+ +
782
+ static int virtconsole_initfn(VirtIOSerialPort *port)
783
+ {
784
+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
785
+ @@ -117,8 +123,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
786
+ }
787
+
788
+ if (vcon->chr) {
789
+ - qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
790
+ - vcon);
791
+ + qemu_chr_add_handlers(vcon->chr, &chr_handlers, vcon);
792
+ }
793
+
794
+ return 0;
795
+ diff --git a/hw/xen_console.c b/hw/xen_console.c
796
+ index 9426d73..e9fcadc 100644
797
+ --- a/hw/xen_console.c
798
+ +++ b/hw/xen_console.c
799
+ @@ -211,6 +211,11 @@ out:
800
+ return ret;
801
+ }
802
+
803
+ +static const QemuChrHandlers xencons_handlers = {
804
+ + .fd_can_read = xencons_can_receive,
805
+ + .fd_read = xencons_receive,
806
+ +};
807
+ +
808
+ static int con_initialise(struct XenDevice *xendev)
809
+ {
810
+ struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
811
+ @@ -231,9 +236,9 @@ static int con_initialise(struct XenDevice *xendev)
812
+ return -1;
813
+
814
+ xen_be_bind_evtchn(&con->xendev);
815
+ - if (con->chr)
816
+ - qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive,
817
+ - NULL, con);
818
+ + if (con->chr) {
819
+ + qemu_chr_add_handlers(con->chr, &xencons_handlers, con);
820
+ + }
821
+
822
+ xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
823
+ con->ring_ref,
824
+ @@ -250,8 +255,9 @@ static void con_disconnect(struct XenDevice *xendev)
825
+ if (!xendev->dev) {
826
+ return;
827
+ }
828
+ - if (con->chr)
829
+ - qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
830
+ + if (con->chr) {
831
+ + qemu_chr_add_handlers(con->chr, NULL, NULL);
832
+ + }
833
+ xen_be_unbind_evtchn(&con->xendev);
834
+
835
+ if (con->sring) {
836
+ diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
837
+ index d20fc41..6605fb1 100644
838
+ --- a/hw/xilinx_uartlite.c
839
+ +++ b/hw/xilinx_uartlite.c
840
+ @@ -195,6 +195,12 @@ static void uart_event(void *opaque, int event)
841
+
842
+ }
843
+
844
+ +static const QemuChrHandlers uart_handlers = {
845
+ + .fd_can_read = uart_can_rx,
846
+ + .fd_read = uart_rx,
847
+ + .fd_event = uart_event,
848
+ +};
849
+ +
850
+ static int xilinx_uartlite_init(SysBusDevice *dev)
851
+ {
852
+ struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
853
+ @@ -207,8 +213,9 @@ static int xilinx_uartlite_init(SysBusDevice *dev)
854
+ sysbus_init_mmio(dev, &s->mmio);
855
+
856
+ s->chr = qemu_char_get_next_serial();
857
+ - if (s->chr)
858
+ - qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
859
+ + if (s->chr) {
860
+ + qemu_chr_add_handlers(s->chr, &uart_handlers, s);
861
+ + }
862
+ return 0;
863
+ }
864
+
865
+ diff --git a/monitor.c b/monitor.c
866
+ index c0e32d6..ce0c90a 100644
867
+ --- a/monitor.c
868
+ +++ b/monitor.c
869
+ @@ -4685,6 +4685,18 @@ static void sortcmdlist(void)
870
+ * End:
871
+ */
872
+
873
+ +static const QemuChrHandlers monitor_handlers = {
874
+ + .fd_can_read = monitor_can_read,
875
+ + .fd_read = monitor_read,
876
+ + .fd_event = monitor_event,
877
+ +};
878
+ +
879
+ +static const QemuChrHandlers monitor_control_handlers = {
880
+ + .fd_can_read = monitor_can_read,
881
+ + .fd_read = monitor_control_read,
882
+ + .fd_event = monitor_control_event,
883
+ +};
884
+ +
885
+ void monitor_init(CharDriverState *chr, int flags)
886
+ {
887
+ static int is_first_init = 1;
888
+ @@ -4707,14 +4719,12 @@ void monitor_init(CharDriverState *chr, int flags)
889
+ if (monitor_ctrl_mode(mon)) {
890
+ mon->mc = g_malloc0(sizeof(MonitorControl));
891
+ /* Control mode requires special handlers */
892
+ - qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
893
+ - monitor_control_event, mon);
894
+ + qemu_chr_add_handlers(chr, &monitor_control_handlers, mon);
895
+ qemu_chr_fe_set_echo(chr, true);
896
+
897
+ json_message_parser_init(&mon->mc->parser, handle_qmp_command);
898
+ } else {
899
+ - qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
900
+ - monitor_event, mon);
901
+ + qemu_chr_add_handlers(chr, &monitor_handlers, mon);
902
+ }
903
+
904
+ QLIST_INSERT_HEAD(&mon_list, mon, entry);
905
+ diff --git a/net/slirp.c b/net/slirp.c
906
+ index afb52c3..07ae92f 100644
907
+ --- a/net/slirp.c
908
+ +++ b/net/slirp.c
909
+ @@ -594,6 +594,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
910
+ slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
911
+ }
912
+
913
+ +static const QemuChrHandlers guestfwd_handlers = {
914
+ + .fd_can_read = guestfwd_can_read,
915
+ + .fd_read = guestfwd_read,
916
+ +};
917
+ +
918
+ static int slirp_guestfwd(SlirpState *s, const char *config_str,
919
+ int legacy_format)
920
+ {
921
+ @@ -659,8 +664,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
922
+ fwd->port = port;
923
+ fwd->slirp = s->slirp;
924
+
925
+ - qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
926
+ - NULL, fwd);
927
+ + qemu_chr_add_handlers(fwd->hd, &guestfwd_handlers, fwd);
928
+ }
929
+ return 0;
930
+
931
+ diff --git a/qemu-char.c b/qemu-char.c
932
+ index 77776dc..97247fb 100644
933
+ --- a/qemu-char.c
934
+ +++ b/qemu-char.c
935
+ @@ -193,19 +193,26 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
936
+ va_end(ap);
937
+ }
938
+
939
+ +static const QemuChrHandlers null_handlers = {
940
+ + /* All handlers are initialised to NULL */
941
+ +};
942
+ +
943
+ void qemu_chr_add_handlers(CharDriverState *s,
944
+ - IOCanReadHandler *fd_can_read,
945
+ - IOReadHandler *fd_read,
946
+ - IOEventHandler *fd_event,
947
+ - void *opaque)
948
+ + const QemuChrHandlers *handlers, void *opaque)
949
+ {
950
+ - if (!opaque && !fd_can_read && !fd_read && !fd_event) {
951
+ + if (!s) {
952
+ + return;
953
+ + }
954
+ + if (!opaque && !handlers) {
955
+ /* chr driver being released. */
956
+ ++s->avail_connections;
957
+ }
958
+ - s->chr_can_read = fd_can_read;
959
+ - s->chr_read = fd_read;
960
+ - s->chr_event = fd_event;
961
+ + if (!handlers) {
962
+ + handlers = &null_handlers;
963
+ + }
964
+ + s->chr_can_read = handlers->fd_can_read;
965
+ + s->chr_read = handlers->fd_read;
966
+ + s->chr_event = handlers->fd_event;
967
+ s->handler_opaque = opaque;
968
+ if (s->chr_update_read_handler)
969
+ s->chr_update_read_handler(s);
970
+ @@ -443,6 +450,12 @@ static void mux_chr_event(void *opaque, int event)
971
+ mux_chr_send_event(d, i, event);
972
+ }
973
+
974
+ +static const QemuChrHandlers mux_chr_handlers = {
975
+ + .fd_can_read = mux_chr_can_read,
976
+ + .fd_read = mux_chr_read,
977
+ + .fd_event = mux_chr_event,
978
+ +};
979
+ +
980
+ static void mux_chr_update_read_handler(CharDriverState *chr)
981
+ {
982
+ MuxDriver *d = chr->opaque;
983
+ @@ -457,8 +470,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
984
+ d->chr_event[d->mux_cnt] = chr->chr_event;
985
+ /* Fix up the real driver with mux routines */
986
+ if (d->mux_cnt == 0) {
987
+ - qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
988
+ - mux_chr_event, chr);
989
+ + qemu_chr_add_handlers(d->drv, &mux_chr_handlers, chr);
990
+ }
991
+ if (d->focus != -1) {
992
+ mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
993
+ diff --git a/qemu-char.h b/qemu-char.h
994
+ index a121e04..ff206cb 100644
995
+ --- a/qemu-char.h
996
+ +++ b/qemu-char.h
997
+ @@ -223,10 +223,15 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
998
+ */
999
+ void qemu_chr_be_event(CharDriverState *s, int event);
1000
+
1001
+ -void qemu_chr_add_handlers(CharDriverState *s,
1002
+ - IOCanReadHandler *fd_can_read,
1003
+ - IOReadHandler *fd_read,
1004
+ - IOEventHandler *fd_event,
1005
+ +
1006
+ +typedef struct QemuChrHandlers {
1007
+ + IOCanReadHandler *fd_can_read;
1008
+ + IOReadHandler *fd_read;
1009
+ + IOHandler *fd_write_unblocked;
1010
+ + IOEventHandler *fd_event;
1011
+ +} QemuChrHandlers;
1012
+ +
1013
+ +void qemu_chr_add_handlers(CharDriverState *s, const QemuChrHandlers *handlers,
1014
+ void *opaque);
1015
+
1016
+ void qemu_chr_generic_open(CharDriverState *s);
1017
+ diff --git a/qtest.c b/qtest.c
1018
+ index fbfab4e..4ab5b69 100644
1019
+ --- a/qtest.c
1020
+ +++ b/qtest.c
1021
+ @@ -416,6 +416,13 @@ static void qtest_event(void *opaque, int event)
1022
+ }
1023
+ }
1024
+
1025
+ +static const QemuChrHandlers test_handlers = {
1026
+ + .fd_can_read = qtest_can_read,
1027
+ + .fd_read = qtest_read,
1028
+ + .fd_event = qtest_event,
1029
+ +};
1030
+ +
1031
+ +
1032
+ int qtest_init(void)
1033
+ {
1034
+ CharDriverState *chr;
1035
+ @@ -425,7 +432,7 @@ int qtest_init(void)
1036
+ configure_icount("0");
1037
+ chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
1038
+
1039
+ - qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
1040
+ + qemu_chr_add_handlers(chr, &test_handlers, chr);
1041
+ qemu_chr_fe_set_echo(chr, true);
1042
+
1043
+ inbuf = g_string_new("");
1044
+ --
1045
+ 1.8.0
1046
+
0102-iohandlers-Add-enable-disable_write_fd_handler-funct.patch ADDED
@@ -0,0 +1,80 @@
1
+ From 448ba28f493820e91b65986901165cb28ff5fd78 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <448ba28f493820e91b65986901165cb28ff5fd78.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Mon, 21 Mar 2011 20:32:58 +0100
7
+ Subject: [PATCH] iohandlers: Add enable/disable_write_fd_handler() functions
8
+
9
+ These will be used to provide a cleaner API for the nonblocking case.
10
+
11
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
12
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
13
+ ---
14
+ iohandler.c | 35 +++++++++++++++++++++++++++++++++++
15
+ main-loop.h | 3 +++
16
+ 2 files changed, 38 insertions(+)
17
+
18
+ diff --git a/iohandler.c b/iohandler.c
19
+ index 60460a6..6cf2cdd 100644
20
+ --- a/iohandler.c
21
+ +++ b/iohandler.c
22
+ @@ -46,6 +46,41 @@ typedef struct IOHandlerRecord {
23
+ static QLIST_HEAD(, IOHandlerRecord) io_handlers =
24
+ QLIST_HEAD_INITIALIZER(io_handlers);
25
+
26
+ +static IOHandlerRecord *find_iohandler(int fd)
27
+ +{
28
+ + IOHandlerRecord *ioh;
29
+ +
30
+ + QLIST_FOREACH(ioh, &io_handlers, next) {
31
+ + if (ioh->fd == fd) {
32
+ + return ioh;
33
+ + }
34
+ + }
35
+ + return NULL;
36
+ +}
37
+ +
38
+ +void enable_write_fd_handler(int fd, IOHandler *fd_write)
39
+ +{
40
+ + IOHandlerRecord *ioh;
41
+ +
42
+ + ioh = find_iohandler(fd);
43
+ + if (!ioh) {
44
+ + return;
45
+ + }
46
+ +
47
+ + ioh->fd_write = fd_write;
48
+ +}
49
+ +
50
+ +void disable_write_fd_handler(int fd)
51
+ +{
52
+ + IOHandlerRecord *ioh;
53
+ +
54
+ + ioh = find_iohandler(fd);
55
+ + if (!ioh) {
56
+ + return;
57
+ + }
58
+ +
59
+ + ioh->fd_write = NULL;
60
+ +}
61
+
62
+ /* XXX: fd_read_poll should be suppressed, but an API change is
63
+ necessary in the character devices to suppress fd_can_read(). */
64
+ diff --git a/main-loop.h b/main-loop.h
65
+ index 326c742..883ad43 100644
66
+ --- a/main-loop.h
67
+ +++ b/main-loop.h
68
+ @@ -166,6 +166,9 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
69
+ typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
70
+ typedef int IOCanReadHandler(void *opaque);
71
+
72
+ +void enable_write_fd_handler(int fd, IOHandler *fd_write);
73
+ +void disable_write_fd_handler(int fd);
74
+ +
75
+ /**
76
+ * qemu_set_fd_handler2: Register a file descriptor with the main loop
77
+ *
78
+ --
79
+ 1.8.0
80
+
0103-char-Add-framework-for-a-write-unblocked-callback.patch ADDED
@@ -0,0 +1,65 @@
1
+ From ea5fefd1ca7fb951c534333a78618ec6d6d89581 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <ea5fefd1ca7fb951c534333a78618ec6d6d89581.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Mon, 21 Mar 2011 21:41:42 +0100
7
+ Subject: [PATCH] char: Add framework for a 'write unblocked' callback
8
+
9
+ The char layer can let users know that the driver will block on further
10
+ input. For users interested in not blocking, they can assign a function
11
+ pointer that will be called back when the driver becomes writable. This
12
+ patch just adds the function pointers to the CharDriverState structure,
13
+ future patches will enable the nonblocking and callback functionality.
14
+
15
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
16
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
17
+ ---
18
+ qemu-char.c | 3 +++
19
+ qemu-char.h | 4 ++++
20
+ 2 files changed, 7 insertions(+)
21
+
22
+ diff --git a/qemu-char.c b/qemu-char.c
23
+ index 97247fb..c9e6e36 100644
24
+ --- a/qemu-char.c
25
+ +++ b/qemu-char.c
26
+ @@ -212,11 +212,14 @@ void qemu_chr_add_handlers(CharDriverState *s,
27
+ }
28
+ s->chr_can_read = handlers->fd_can_read;
29
+ s->chr_read = handlers->fd_read;
30
+ + s->chr_write_unblocked = handlers->fd_write_unblocked;
31
+ s->chr_event = handlers->fd_event;
32
+ s->handler_opaque = opaque;
33
+ if (s->chr_update_read_handler)
34
+ s->chr_update_read_handler(s);
35
+
36
+ + s->write_blocked = false;
37
+ +
38
+ /* We're connecting to an already opened device, so let's make sure we
39
+ also get the open event */
40
+ if (s->opened) {
41
+ diff --git a/qemu-char.h b/qemu-char.h
42
+ index ff206cb..9e1b0f1 100644
43
+ --- a/qemu-char.h
44
+ +++ b/qemu-char.h
45
+ @@ -63,6 +63,9 @@ struct CharDriverState {
46
+ IOEventHandler *chr_event;
47
+ IOCanReadHandler *chr_can_read;
48
+ IOReadHandler *chr_read;
49
+ + IOHandler *chr_write_unblocked;
50
+ + void (*chr_enable_write_fd_handler)(struct CharDriverState *chr);
51
+ + void (*chr_disable_write_fd_handler)(struct CharDriverState *chr);
52
+ void *handler_opaque;
53
+ void (*chr_close)(struct CharDriverState *chr);
54
+ void (*chr_accept_input)(struct CharDriverState *chr);
55
+ @@ -75,6 +78,7 @@ struct CharDriverState {
56
+ char *filename;
57
+ int opened;
58
+ int avail_connections;
59
+ + bool write_blocked; /* Are we in a blocked state? */
60
+ QTAILQ_ENTRY(CharDriverState) next;
61
+ };
62
+
63
+ --
64
+ 1.8.0
65
+
0104-char-Update-send_all-to-handle-nonblocking-chardev-w.patch ADDED
@@ -0,0 +1,176 @@
1
+ From dfbe8c51243ecd2ad33037cfbbb37440cc3d03ee Mon Sep 17 00:00:00 2001
2
+ Message-Id: <dfbe8c51243ecd2ad33037cfbbb37440cc3d03ee.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Mon, 21 Mar 2011 22:00:27 +0100
7
+ Subject: [PATCH] char: Update send_all() to handle nonblocking chardev write
8
+ requests
9
+
10
+ The send_all function is modified to return to the caller in case the
11
+ driver cannot handle any more data. It returns -EAGAIN or
12
+ WSAEWOULDBLOCK on non-Windows and Windows platforms respectively. This
13
+ is only done when the caller sets a callback function handler indicating
14
+ it's not interested in blocking till the driver has written out all the
15
+ data.
16
+
17
+ Currently there's no driver or caller that supports this. Future
18
+ commits will add such capability.
19
+
20
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
21
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
22
+ ---
23
+ qemu-char.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
24
+ qemu_socket.h | 2 +-
25
+ 2 files changed, 64 insertions(+), 7 deletions(-)
26
+
27
+ diff --git a/qemu-char.c b/qemu-char.c
28
+ index c9e6e36..53803a3 100644
29
+ --- a/qemu-char.c
30
+ +++ b/qemu-char.c
31
+ @@ -509,7 +509,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
32
+
33
+
34
+ #ifdef _WIN32
35
+ -int send_all(int fd, const void *buf, int len1)
36
+ +static int do_send(int fd, const void *buf, int len1, bool nonblock)
37
+ {
38
+ int ret, len;
39
+
40
+ @@ -517,9 +517,14 @@ int send_all(int fd, const void *buf, int len1)
41
+ while (len > 0) {
42
+ ret = send(fd, buf, len, 0);
43
+ if (ret < 0) {
44
+ + if (nonblock && len1 - len) {
45
+ + return len1 - len;
46
+ + }
47
+ errno = WSAGetLastError();
48
+ if (errno != WSAEWOULDBLOCK) {
49
+ return -1;
50
+ + } else if (errno == WSAEWOULDBLOCK && nonblock) {
51
+ + return WSAEWOULDBLOCK;
52
+ }
53
+ } else if (ret == 0) {
54
+ break;
55
+ @@ -533,7 +538,7 @@ int send_all(int fd, const void *buf, int len1)
56
+
57
+ #else
58
+
59
+ -int send_all(int fd, const void *_buf, int len1)
60
+ +static int do_send(int fd, const void *_buf, int len1, bool nonblock)
61
+ {
62
+ int ret, len;
63
+ const uint8_t *buf = _buf;
64
+ @@ -542,8 +547,15 @@ int send_all(int fd, const void *_buf, int len1)
65
+ while (len > 0) {
66
+ ret = write(fd, buf, len);
67
+ if (ret < 0) {
68
+ - if (errno != EINTR && errno != EAGAIN)
69
+ + if (nonblock && len1 - len) {
70
+ + return len1 - len;
71
+ + }
72
+ + if (errno == EAGAIN && nonblock) {
73
+ + return -EAGAIN;
74
+ + }
75
+ + if (errno != EINTR && errno != EAGAIN) {
76
+ return -1;
77
+ + }
78
+ } else if (ret == 0) {
79
+ break;
80
+ } else {
81
+ @@ -558,6 +570,44 @@ int send_all(int fd, const void *_buf, int len1)
82
+ #define STDIO_MAX_CLIENTS 1
83
+ static int stdio_nb_clients;
84
+
85
+ +int send_all(CharDriverState *chr, int fd, const void *_buf, int len1)
86
+ +{
87
+ + int ret, eagain_errno;
88
+ + bool nonblock;
89
+ +
90
+ + if (chr && chr->write_blocked) {
91
+ + /*
92
+ + * The caller should not send us data while we're blocked,
93
+ + * but this can happen when multiple writers are woken at once,
94
+ + * so simply return -EAGAIN.
95
+ + */
96
+ + return -EAGAIN;
97
+ + }
98
+ +
99
+ + nonblock = false;
100
+ + /*
101
+ + * Ensure the char backend is able to receive and handle the
102
+ + * 'write unblocked' event before we turn on nonblock support.
103
+ + */
104
+ + if (chr && chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) {
105
+ + nonblock = true;
106
+ + }
107
+ + ret = do_send(fd, _buf, len1, nonblock);
108
+ +
109
+ +#ifdef _WIN32
110
+ + eagain_errno = WSAEWOULDBLOCK;
111
+ +#else
112
+ + eagain_errno = -EAGAIN;
113
+ +#endif
114
+ +
115
+ + if (nonblock && (ret == eagain_errno || (ret >= 0 && ret < len1))) {
116
+ + /* Update fd handler to wake up when chr becomes writable */
117
+ + chr->chr_enable_write_fd_handler(chr);
118
+ + chr->write_blocked = true;
119
+ + }
120
+ + return ret;
121
+ +}
122
+ +
123
+ #ifndef _WIN32
124
+
125
+ typedef struct {
126
+ @@ -569,7 +619,7 @@ typedef struct {
127
+ static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
128
+ {
129
+ FDCharDriver *s = chr->opaque;
130
+ - return send_all(s->fd_out, buf, len);
131
+ + return send_all(chr, s->fd_out, buf, len);
132
+ }
133
+
134
+ static int fd_chr_read_poll(void *opaque)
135
+ @@ -888,7 +938,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
136
+ pty_chr_update_read_handler(chr);
137
+ return 0;
138
+ }
139
+ - return send_all(s->fd, buf, len);
140
+ + return send_all(chr, s->fd, buf, len);
141
+ }
142
+
143
+ static int pty_chr_read_poll(void *opaque)
144
+ @@ -2179,8 +2229,15 @@ static void tcp_closed(void *opaque)
145
+ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
146
+ {
147
+ TCPCharDriver *s = chr->opaque;
148
+ +
149
+ if (s->connected) {
150
+ - return send_all(s->fd, buf, len);
151
+ + int ret;
152
+ +
153
+ + ret = send_all(chr, s->fd, buf, len);
154
+ + if (ret == -1 && errno == EPIPE) {
155
+ + tcp_closed(chr);
156
+ + }
157
+ + return ret;
158
+ } else {
159
+ /* XXX: indicate an error ? */
160
+ return len;
161
+ diff --git a/qemu_socket.h b/qemu_socket.h
162
+ index 02490ad..cceab98 100644
163
+ --- a/qemu_socket.h
164
+ +++ b/qemu_socket.h
165
+ @@ -36,7 +36,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
166
+ int socket_set_cork(int fd, int v);
167
+ void socket_set_block(int fd);
168
+ void socket_set_nonblock(int fd);
169
+ -int send_all(int fd, const void *buf, int len1);
170
+ +int send_all(CharDriverState *chr, int fd, const void *buf, int len1);
171
+
172
+ /* callback function for nonblocking connect
173
+ * valid fd on success, negative error code on failure
174
+ --
175
+ 1.8.0
176
+
0105-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch ADDED
@@ -0,0 +1,85 @@
1
+ From 26139c9fd71229699c6d59c31631a539ac3830fd Mon Sep 17 00:00:00 2001
2
+ Message-Id: <26139c9fd71229699c6d59c31631a539ac3830fd.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Mon, 21 Mar 2011 22:02:47 +0100
7
+ Subject: [PATCH] char: Equip the unix/tcp backend to handle nonblocking
8
+ writes#
9
+
10
+ Now that the infrastructure is in place to return -EAGAIN to callers,
11
+ individual char drivers can set their update_fd_handlers() function to
12
+ set or remove an fd's write handler. This handler checks if the driver
13
+ became writable.
14
+
15
+ A generic callback routine is used for unblocking writes and letting
16
+ users of chardevs know that a driver became writable again.
17
+
18
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
19
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
20
+ ---
21
+ qemu-char.c | 34 ++++++++++++++++++++++++++++++++++
22
+ 1 file changed, 34 insertions(+)
23
+
24
+ diff --git a/qemu-char.c b/qemu-char.c
25
+ index 53803a3..e7cd42a 100644
26
+ --- a/qemu-char.c
27
+ +++ b/qemu-char.c
28
+ @@ -106,6 +106,19 @@
29
+ static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
30
+ QTAILQ_HEAD_INITIALIZER(chardevs);
31
+
32
+ +/*
33
+ + * Generic routine that gets called when chardev becomes writable.
34
+ + * Lets chardev user know it's OK to send more data.
35
+ + */
36
+ +static void char_write_unblocked(void *opaque)
37
+ +{
38
+ + CharDriverState *chr = opaque;
39
+ +
40
+ + chr->write_blocked = false;
41
+ + chr->chr_disable_write_fd_handler(chr);
42
+ + chr->chr_write_unblocked(chr->handler_opaque);
43
+ +}
44
+ +
45
+ void qemu_chr_be_event(CharDriverState *s, int event)
46
+ {
47
+ /* Keep track if the char device is open */
48
+ @@ -2508,6 +2521,25 @@ static void tcp_chr_close(CharDriverState *chr)
49
+ qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
50
+ }
51
+
52
+ +static void tcp_enable_write_fd_handler(CharDriverState *chr)
53
+ +{
54
+ + TCPCharDriver *s = chr->opaque;
55
+ +
56
+ + /*
57
+ + * This function is called only after tcp_chr_connect() is called
58
+ + * (either in 'server' mode or client mode. So we're sure of
59
+ + * s->fd being initialised.
60
+ + */
61
+ + enable_write_fd_handler(s->fd, char_write_unblocked);
62
+ +}
63
+ +
64
+ +static void tcp_disable_write_fd_handler(CharDriverState *chr)
65
+ +{
66
+ + TCPCharDriver *s = chr->opaque;
67
+ +
68
+ + disable_write_fd_handler(s->fd);
69
+ +}
70
+ +
71
+ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
72
+ {
73
+ CharDriverState *chr = NULL;
74
+ @@ -2563,6 +2595,8 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
75
+ chr->chr_close = tcp_chr_close;
76
+ chr->get_msgfd = tcp_get_msgfd;
77
+ chr->chr_add_client = tcp_chr_add_client;
78
+ + chr->chr_enable_write_fd_handler = tcp_enable_write_fd_handler;
79
+ + chr->chr_disable_write_fd_handler = tcp_disable_write_fd_handler;
80
+
81
+ if (is_listen) {
82
+ s->listen_fd = fd;
83
+ --
84
+ 1.8.0
85
+
0106-char-Throttle-when-host-connection-is-down.patch ADDED
@@ -0,0 +1,60 @@
1
+ From c2ddb156db52808a89d91edf5bb1449f226d3ecd Mon Sep 17 00:00:00 2001
2
+ Message-Id: <c2ddb156db52808a89d91edf5bb1449f226d3ecd.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Mon, 21 Mar 2011 22:05:10 +0100
7
+ Subject: [PATCH] char: Throttle when host connection is down#
8
+
9
+ When the host-side connection goes down, throttle the virtio-serial bus
10
+ and later unthrottle when a connection gets established. This helps
11
+ prevent any lost IO (guest->host) while the host connection was down.
12
+
13
+ Bugzilla: 621484
14
+
15
+ This commit actually helps the bug mentioned above as no writes will now
16
+ get lost because of the throttling done here. With just the patches
17
+ sent earlier for that bug, one write will end up getting lost in the
18
+ worst case (host d/c, guest write, host connect).
19
+
20
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
21
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
22
+ ---
23
+ qemu-char.c | 14 ++++++++++++++
24
+ 1 file changed, 14 insertions(+)
25
+
26
+ diff --git a/qemu-char.c b/qemu-char.c
27
+ index e7cd42a..5c71f0c 100644
28
+ --- a/qemu-char.c
29
+ +++ b/qemu-char.c
30
+ @@ -140,6 +140,9 @@ static void qemu_chr_fire_open_event(void *opaque)
31
+ {
32
+ CharDriverState *s = opaque;
33
+ qemu_chr_be_event(s, CHR_EVENT_OPENED);
34
+ + if (s->write_blocked) {
35
+ + char_write_unblocked(s);
36
+ + }
37
+ qemu_free_timer(s->open_timer);
38
+ s->open_timer = NULL;
39
+ }
40
+ @@ -2249,6 +2252,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
41
+ ret = send_all(chr, s->fd, buf, len);
42
+ if (ret == -1 && errno == EPIPE) {
43
+ tcp_closed(chr);
44
+ +
45
+ + if (chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) {
46
+ + /*
47
+ + * Since we haven't written out anything, let's say
48
+ + * we're throttled. This will prevent any output from
49
+ + * the guest getting lost if host-side chardev goes
50
+ + * down. Unthrottle when we re-connect.
51
+ + */
52
+ + chr->write_blocked = true;
53
+ + return 0;
54
+ + }
55
+ }
56
+ return ret;
57
+ } else {
58
+ --
59
+ 1.8.0
60
+
0107-virtio-console-Enable-port-throttling-when-chardev-i.patch ADDED
@@ -0,0 +1,53 @@
1
+ From afae0976cf4e3ba7f2810c1afaecac96646a2a2b Mon Sep 17 00:00:00 2001
2
+ Message-Id: <afae0976cf4e3ba7f2810c1afaecac96646a2a2b.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Mon, 21 Mar 2011 22:06:41 +0100
7
+ Subject: [PATCH] virtio-console: Enable port throttling when chardev is slow
8
+ to consume data
9
+
10
+ When a chardev indicates it can't accept more data, we tell the
11
+ virtio-serial code to stop sending us any more data till we tell
12
+ otherwise. This helps in guests continuing to run normally while the vq
13
+ keeps getting full and eventually the guest stops queueing more data.
14
+ As soon as the chardev indicates it can accept more data, start pushing!
15
+
16
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
17
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
18
+ ---
19
+ hw/virtio-console.c | 11 +++++++++++
20
+ 1 file changed, 11 insertions(+)
21
+
22
+ diff --git a/hw/virtio-console.c b/hw/virtio-console.c
23
+ index 066590c..2b5e515 100644
24
+ --- a/hw/virtio-console.c
25
+ +++ b/hw/virtio-console.c
26
+ @@ -20,6 +20,16 @@ typedef struct VirtConsole {
27
+ CharDriverState *chr;
28
+ } VirtConsole;
29
+
30
+ +/*
31
+ + * Callback function that's called from chardevs when backend becomes
32
+ + * writable.
33
+ + */
34
+ +static void chr_write_unblocked(void *opaque)
35
+ +{
36
+ + VirtConsole *vcon = opaque;
37
+ +
38
+ + virtio_serial_throttle_port(&vcon->port, false);
39
+ +}
40
+
41
+ /* Callback function that's called when the guest sends us data */
42
+ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
43
+ @@ -110,6 +120,7 @@ static const QemuChrHandlers chr_handlers = {
44
+ .fd_can_read = chr_can_read,
45
+ .fd_read = chr_read,
46
+ .fd_event = chr_event,
47
+ + .fd_write_unblocked = chr_write_unblocked,
48
+ };
49
+
50
+ static int virtconsole_initfn(VirtIOSerialPort *port)
51
+ --
52
+ 1.8.0
53
+
0108-spice-qemu-char.c-add-throttling.patch ADDED
@@ -0,0 +1,138 @@
1
+ From bffc95c205b473df9bba81dbf676504d0981d392 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <bffc95c205b473df9bba81dbf676504d0981d392.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Alon Levy <alevy@redhat.com>
6
+ Date: Tue, 22 Mar 2011 12:27:59 +0200
7
+ Subject: [PATCH] spice-qemu-char.c: add throttling
8
+
9
+ BZ: 672191
10
+
11
+ upstream: not submitted (explained below)
12
+
13
+ Adds throttling support to spicevmc chardev. Uses a timer to avoid recursing:
14
+ 1. spice-server: reds.c: read_from_vdi_port
15
+ 2. qemu: spice-qemu-char.c: vmc_read
16
+ 3. chr_write_unblocked
17
+ (calls virtio_serial_throttle_port(port, false))
18
+ 4. qemu: virtio ...
19
+ 5. qemu: spice-qemu-char.c: spice_chr_write
20
+ 6. qemu: spice-qemu-char.c: wakeup (calls into spice-server)
21
+ 7. spice-server: ...
22
+ 8. qemu: spice-qemu-char.c: vmc_read
23
+
24
+ Instead, in vmc_read if we were throttled and we are just about to return
25
+ all the bytes we will set a timer to be triggered immediately to call
26
+ chr_write_unblocked. Then we return after 2 above, and 3 is called from the
27
+ timer callback. This also means we can later remove some ugly recursion protection
28
+ from spice-server.
29
+
30
+ The other tricky point in this patch is not returning the leftover chunk twice.
31
+ When we throttle, by definition we have data that spice server didn't consume.
32
+ It is being kept by virtio-serial, and by us. The next vmc_read callback needs
33
+ to not return it, but just do unthrottling. Then virtio will give us the remaining
34
+ chunk as usual in spice_chr_write, and we will pass it to spice server in the
35
+ next vmc_read.
36
+
37
+ This patch relies on Amit's series to expose throttling to chardev's, which
38
+ was not accepted upstream, and will not be accepted upstream until the mainloop
39
+ is reworked to use glib.
40
+
41
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
42
+ ---
43
+ spice-qemu-char.c | 39 +++++++++++++++++++++++++++++++++++----
44
+ 1 file changed, 35 insertions(+), 4 deletions(-)
45
+
46
+ diff --git a/spice-qemu-char.c b/spice-qemu-char.c
47
+ index 09aa22d..fba2bfb 100644
48
+ --- a/spice-qemu-char.c
49
+ +++ b/spice-qemu-char.c
50
+ @@ -1,4 +1,6 @@
51
+ #include "config-host.h"
52
+ +#include "qemu-common.h"
53
+ +#include "qemu-timer.h"
54
+ #include "trace.h"
55
+ #include "ui/qemu-spice.h"
56
+ #include <spice.h>
57
+ @@ -25,6 +27,7 @@ typedef struct SpiceCharDriver {
58
+ uint8_t *datapos;
59
+ ssize_t bufsize, datalen;
60
+ uint32_t debug;
61
+ + QEMUTimer *unblock_timer;
62
+ } SpiceCharDriver;
63
+
64
+ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
65
+ @@ -50,6 +53,17 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
66
+ return out;
67
+ }
68
+
69
+ +static void spice_chr_unblock(void *opaque)
70
+ +{
71
+ + SpiceCharDriver *scd = opaque;
72
+ +
73
+ + if (scd->chr->chr_write_unblocked == NULL) {
74
+ + dprintf(scd, 1, "%s: backend doesn't support unthrottling.\n", __func__);
75
+ + return;
76
+ + }
77
+ + scd->chr->chr_write_unblocked(scd->chr->handler_opaque);
78
+ +}
79
+ +
80
+ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
81
+ {
82
+ SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
83
+ @@ -61,9 +75,16 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
84
+ scd->datapos += bytes;
85
+ scd->datalen -= bytes;
86
+ assert(scd->datalen >= 0);
87
+ - if (scd->datalen == 0) {
88
+ - scd->datapos = 0;
89
+ - }
90
+ + }
91
+ + if (scd->datalen == 0 && scd->chr->write_blocked) {
92
+ + dprintf(scd, 1, "%s: unthrottling (%d)\n", __func__, bytes);
93
+ + scd->chr->write_blocked = false;
94
+ + /*
95
+ + * set a timer instead of calling scd->chr->chr_write_unblocked directly,
96
+ + * because that will call back into spice_chr_write (see
97
+ + * virtio-console.c:chr_write_unblocked), which is unwanted.
98
+ + */
99
+ + qemu_mod_timer(scd->unblock_timer, 0);
100
+ }
101
+ trace_spice_vmc_read(bytes, len);
102
+ return bytes;
103
+ @@ -135,6 +156,7 @@ static void vmc_unregister_interface(SpiceCharDriver *scd)
104
+ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
105
+ {
106
+ SpiceCharDriver *s = chr->opaque;
107
+ + int read_bytes;
108
+
109
+ dprintf(s, 2, "%s: %d\n", __func__, len);
110
+ vmc_register_interface(s);
111
+ @@ -147,7 +169,15 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
112
+ s->datapos = s->buffer;
113
+ s->datalen = len;
114
+ spice_server_char_device_wakeup(&s->sin);
115
+ - return len;
116
+ + read_bytes = len - s->datalen;
117
+ + if (read_bytes != len) {
118
+ + dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__,
119
+ + read_bytes, len, s->bufsize);
120
+ + s->chr->write_blocked = true;
121
+ + /* We'll get passed in the unconsumed data with the next call */
122
+ + s->datalen = 0;
123
+ + }
124
+ + return read_bytes;
125
+ }
126
+
127
+ static void spice_chr_close(struct CharDriverState *chr)
128
+ @@ -225,6 +255,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
129
+ chr->chr_close = spice_chr_close;
130
+ chr->chr_guest_open = spice_chr_guest_open;
131
+ chr->chr_guest_close = spice_chr_guest_close;
132
+ + s->unblock_timer = qemu_new_timer_ms(vm_clock, spice_chr_unblock, s);
133
+
134
+ #if SPICE_SERVER_VERSION < 0x000901
135
+ /* See comment in vmc_state() */
136
+ --
137
+ 1.8.0
138
+
0109-spice-qemu-char.c-remove-intermediate-buffer.patch ADDED
@@ -0,0 +1,76 @@
1
+ From 52b76076caf6f3f92b83a6f34b70417ddcd3d9d7 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <52b76076caf6f3f92b83a6f34b70417ddcd3d9d7.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Alon Levy <alevy@redhat.com>
6
+ Date: Tue, 22 Mar 2011 12:28:00 +0200
7
+ Subject: [PATCH] spice-qemu-char.c: remove intermediate buffer
8
+
9
+ BZ: 672191
10
+ upstream: not submitted (explained below)
11
+
12
+ virtio-serial's buffer is valid when it calls us, and we don't
13
+ access it otherwise: vmc_read is only called in response to wakeup,
14
+ or else we set datalen=0 and throttle. Then vmc_read is called back,
15
+ we return 0 (not accessing the buffer) and set the timer to unthrottle.
16
+
17
+ Also make datalen int and not ssize_t (to fit spice_chr_write signature).
18
+
19
+ This relied on the previous patch that introduces throttling, which
20
+ can't go upstream right now as explained in that patch.
21
+
22
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
23
+ ---
24
+ spice-qemu-char.c | 18 ++++++------------
25
+ 1 file changed, 6 insertions(+), 12 deletions(-)
26
+
27
+ diff --git a/spice-qemu-char.c b/spice-qemu-char.c
28
+ index fba2bfb..ef44bc0 100644
29
+ --- a/spice-qemu-char.c
30
+ +++ b/spice-qemu-char.c
31
+ @@ -23,9 +23,8 @@ typedef struct SpiceCharDriver {
32
+ SpiceCharDeviceInstance sin;
33
+ char *subtype;
34
+ bool active;
35
+ - uint8_t *buffer;
36
+ - uint8_t *datapos;
37
+ - ssize_t bufsize, datalen;
38
+ + const uint8_t *datapos;
39
+ + int datalen;
40
+ uint32_t debug;
41
+ QEMUTimer *unblock_timer;
42
+ } SpiceCharDriver;
43
+ @@ -69,7 +68,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
44
+ SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
45
+ int bytes = MIN(len, scd->datalen);
46
+
47
+ - dprintf(scd, 2, "%s: %p %d/%d/%zd\n", __func__, scd->datapos, len, bytes, scd->datalen);
48
+ + dprintf(scd, 2, "%s: %p %d/%d/%d\n", __func__, scd->datapos, len, bytes, scd->datalen);
49
+ if (bytes > 0) {
50
+ memcpy(buf, scd->datapos, bytes);
51
+ scd->datapos += bytes;
52
+ @@ -161,18 +160,13 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
53
+ dprintf(s, 2, "%s: %d\n", __func__, len);
54
+ vmc_register_interface(s);
55
+ assert(s->datalen == 0);
56
+ - if (s->bufsize < len) {
57
+ - s->bufsize = len;
58
+ - s->buffer = g_realloc(s->buffer, s->bufsize);
59
+ - }
60
+ - memcpy(s->buffer, buf, len);
61
+ - s->datapos = s->buffer;
62
+ + s->datapos = buf;
63
+ s->datalen = len;
64
+ spice_server_char_device_wakeup(&s->sin);
65
+ read_bytes = len - s->datalen;
66
+ if (read_bytes != len) {
67
+ - dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__,
68
+ - read_bytes, len, s->bufsize);
69
+ + dprintf(s, 1, "%s: throttling: %d < %d\n", __func__,
70
+ + read_bytes, len);
71
+ s->chr->write_blocked = true;
72
+ /* We'll get passed in the unconsumed data with the next call */
73
+ s->datalen = 0;
74
+ --
75
+ 1.8.0
76
+
0110-usb-redir-Add-flow-control-support.patch ADDED
@@ -0,0 +1,69 @@
1
+ From 4e6a76dd0e35b00e9592a53afc8cffac4cc35951 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <4e6a76dd0e35b00e9592a53afc8cffac4cc35951.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Hans de Goede <hdegoede@redhat.com>
6
+ Date: Tue, 19 Jul 2011 10:56:19 +0200
7
+ Subject: [PATCH] usb-redir: Add flow control support
8
+
9
+ Signed-off-by: Hans de Goede <hdegoede@redhat.com>
10
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
11
+ ---
12
+ hw/usb/redirect.c | 22 ++++++++++++++++++++--
13
+ 1 file changed, 20 insertions(+), 2 deletions(-)
14
+
15
+ diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
16
+ index c921d2d..dfb1773 100644
17
+ --- a/hw/usb/redirect.c
18
+ +++ b/hw/usb/redirect.c
19
+ @@ -239,8 +239,9 @@ static int usbredir_read(void *priv, uint8_t *data, int count)
20
+ static int usbredir_write(void *priv, uint8_t *data, int count)
21
+ {
22
+ USBRedirDevice *dev = priv;
23
+ + int r;
24
+
25
+ - if (!dev->cs->opened) {
26
+ + if (!dev->cs->opened || dev->cs->write_blocked) {
27
+ return 0;
28
+ }
29
+
30
+ @@ -249,7 +250,16 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
31
+ return 0;
32
+ }
33
+
34
+ - return qemu_chr_fe_write(dev->cs, data, count);
35
+ + r - qemu_chr_fe_write(dev->cs, data, count);
36
+ +
37
+ + if (r < 0) {
38
+ + if (dev->cs->write_blocked) {
39
+ + return 0;
40
+ + }
41
+ + return -1;
42
+ + }
43
+ +
44
+ + return r;
45
+ }
46
+
47
+ /*
48
+ @@ -1037,10 +1047,18 @@ static void usbredir_chardev_event(void *opaque, int event)
49
+ }
50
+ }
51
+
52
+ +static void usbredir_chardev_write_unblocked(void *opaque)
53
+ +{
54
+ + USBRedirDevice *dev = opaque;
55
+ +
56
+ + usbredirparser_do_write(dev->parser);
57
+ +}
58
+ +
59
+ static const QemuChrHandlers usbredir_chr_handlers = {
60
+ .fd_can_read = usbredir_chardev_can_read,
61
+ .fd_read = usbredir_chardev_read,
62
+ .fd_event = usbredir_chardev_event,
63
+ + .fd_write_unblocked = usbredir_chardev_write_unblocked,
64
+ };
65
+
66
+ /*
67
+ --
68
+ 1.8.0
69
+
0111-char-Disable-write-callback-if-throttled-chardev-is-.patch ADDED
@@ -0,0 +1,40 @@
1
+ From 736b3ad749e5c60de44d4c5836b59d2287b6b918 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <736b3ad749e5c60de44d4c5836b59d2287b6b918.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Amit Shah <amit.shah@redhat.com>
6
+ Date: Fri, 2 Dec 2011 15:42:55 +0530
7
+ Subject: [PATCH] char: Disable write callback if throttled chardev is
8
+ detached
9
+
10
+ If a throttled chardev is detached from the frontend device, all future
11
+ callbacks should be suppressed. Not doing this results in a segfault.
12
+
13
+ Bugzilla: 745758
14
+ Upstream: Not applicable, since throttling is a RHEL6-only feature.
15
+
16
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
17
+ Signed-off-by: Cole Robinson <crobinso@redhat.com>
18
+ ---
19
+ qemu-char.c | 5 +++++
20
+ 1 file changed, 5 insertions(+)
21
+
22
+ diff --git a/qemu-char.c b/qemu-char.c
23
+ index 5c71f0c..16ad6b6 100644
24
+ --- a/qemu-char.c
25
+ +++ b/qemu-char.c
26
+ @@ -224,6 +224,11 @@ void qemu_chr_add_handlers(CharDriverState *s,
27
+ ++s->avail_connections;
28
+ }
29
+ if (!handlers) {
30
+ + if (s->write_blocked) {
31
+ + /* Ensure we disable the callback if we were throttled */
32
+ + s->chr_disable_write_fd_handler(s);
33
+ + /* s->write_blocked is cleared below */
34
+ + }
35
+ handlers = &null_handlers;
36
+ }
37
+ s->chr_can_read = handlers->fd_can_read;
38
+ --
39
+ 1.8.0
40
+
0112-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch ADDED
@@ -0,0 +1,57 @@
1
+ From 1f54fab0e8f692986254b69c607f4151d9743260 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <1f54fab0e8f692986254b69c607f4151d9743260.1354903384.git.crobinso@redhat.com>
3
+ In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
4
+ References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
5
+ From: Alon Levy <alevy@redhat.com>
6
+ Date: Fri, 16 Nov 2012 16:24:47 +0200
7
+ Subject: [PATCH] hw/virtio-serial-bus: replay guest open on destination
8
+
9
+ This is rewrite of a patch carried in Fedora previously based
10
+ on new code upstream, here is the original message, it still applies:
11
+ (the original fedora patch was commit id
12
+ a9bc20afc1f0604ee81c23b7c67d627e51d2e8d4, this is useful for grepping in
13
+ logs, it isn't in upstream)
14
+
15
+ When migrating a host with with a spice agent running the mouse becomes
16
+ non operational after the migration. This is rhbz #725965.
17
+
18
+ The problem is that after migration spice doesn't know the guest agent
19
+ is open. Spice is just a char dev here. And a chardev cannot query it's
20
+ device, the device has to let the chardev know when it is open. Right
21
+ now after migration the chardev which is recreated is in it's default
22
+ state, which assumes the guest is disconnected.
23
+
24
+ Char devices carry no information across migration, but the
25
+ virtio-serial does already carry the guest_connected state. This patch
26
+ passes that bit to the chardev.
27
+ ---
28
+ hw/virtio-serial-bus.c | 6 ++++++
29
+ 1 file changed, 6 insertions(+)
30
+
31
+ diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
32
+ index 155da58..fd19984 100644
33
+ --- a/hw/virtio-serial-bus.c
34
+ +++ b/hw/virtio-serial-bus.c
35
+ @@ -641,6 +641,7 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
36
+ VirtIOSerial *s = opaque;
37
+ VirtIOSerialPort *port;
38
+ uint8_t host_connected;
39
+ + VirtIOSerialPortClass *vsc;
40
+
41
+ for (i = 0 ; i < s->post_load.nr_active_ports; ++i) {
42
+ port = s->post_load.connected[i].port;
43
+ @@ -653,6 +654,11 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
44
+ send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN,
45
+ port->host_connected);
46
+ }
47
+ + vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
48
+ + if (port->guest_connected && vsc->guest_open) {
49
+ + /* replay guest open */
50
+ + vsc->guest_open(port);
51
+ + }
52
+ }
53
+ g_free(s->post_load.connected);
54
+ s->post_load.connected = NULL;
55
+ --
56
+ 1.8.0
57
+
file modified
+44 -0
qemu.spec CHANGED
@@ -137,6 +137,25 @@ ExclusiveArch: %{kvm_archs}
137
137
%endif
138
138
139
139
Source0: http://wiki.qemu-project.org/download/%{name}-%{version}.tar.bz2
140
+ # libcacard build fixes (heading upstream)
141
+ Patch1: 0000-libcacard-fix-missing-symbols-in-libcacard.so.patch
142
+ Patch2: 0001-configure-move-vscclient-binary-under-libcacard.patch
143
+ # Fix migration from qemu-kvm 1.2 to qemu 1.3
144
+ Patch3: 0002-Fix-migration-from-qemu-kvm-1.2.patch
145
+ # Flow control series
146
+ Patch4: 0100-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
147
+ Patch5: 0101-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
148
+ Patch6: 0102-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
149
+ Patch7: 0103-char-Add-framework-for-a-write-unblocked-callback.patch
150
+ Patch8: 0104-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
151
+ Patch9: 0105-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
152
+ Patch10: 0106-char-Throttle-when-host-connection-is-down.patch
153
+ Patch11: 0107-virtio-console-Enable-port-throttling-when-chardev-i.patch
154
+ Patch12: 0108-spice-qemu-char.c-add-throttling.patch
155
+ Patch13: 0109-spice-qemu-char.c-remove-intermediate-buffer.patch
156
+ Patch14: 0110-usb-redir-Add-flow-control-support.patch
157
+ Patch15: 0111-char-Disable-write-callback-if-throttled-chardev-is-.patch
158
+ Patch16: 0112-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch
140
159
141
160
Source1: qemu.binfmt
142
161
@@ -607,6 +626,22 @@ CAC emulation development files.
607
626
608
627
%prep
609
628
%setup -q
629
+ %patch1 -p1
630
+ %patch2 -p1
631
+ %patch3 -p1
632
+ %patch4 -p1
633
+ %patch5 -p1
634
+ %patch6 -p1
635
+ %patch7 -p1
636
+ %patch8 -p1
637
+ %patch9 -p1
638
+ %patch10 -p1
639
+ %patch11 -p1
640
+ %patch12 -p1
641
+ %patch13 -p1
642
+ %patch14 -p1
643
+ %patch15 -p1
644
+ %patch16 -p1
610
645
611
646
612
647
%build
@@ -1225,6 +1260,15 @@ fi
1225
1260
%{_libdir}/pkgconfig/libcacard.pc
1226
1261
1227
1262
%changelog
1263
+ * Fri Dec 07 2012 Cole Robinson <crobinso@redhat.com> - 2:1.3.0-1
1264
+ - Switch base tarball from qemu-kvm to qemu
1265
+ - qemu 1.3 release
1266
+ - Option to use linux VFIO driver to assign PCI devices
1267
+ - Many USB3 improvements
1268
+ - New paravirtualized hardware random number generator device.
1269
+ - Support for Glusterfs volumes with "gluster://" -drive URI
1270
+ - Block job commands for live block commit and storage migration
1271
+
1228
1272
* Wed Nov 28 2012 Alon Levy <alevy@redhat.com> - 2:1.2.0-25
1229
1273
* Merge libcacard into qemu, since they both use the same sources now.
1230
1274
file modified
+1 -1
sources CHANGED
@@ -1 +1 @@
1
- d7b18b673c48abfee65a9c0245df0415 qemu-kvm-1.2.0.tar.gz
1
+ a4030ddd2ba324152a97d65d3c0b247d qemu-1.3.0.tar.bz2