diff --git a/.gitignore b/.gitignore index e21efef..7da4d22 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,10 @@ qemu-kvm-0.13.0-25fdf4a.tar.gz /qemu-1.3.0.tar.bz2 /qemu-1.4.0.tar.bz2 /qemu-1.4.1.tar.bz2 -/qemu-1.4.2.tar.bz2 +/qemu-1.5.0.tar.bz2 +/qemu-1.5.1.tar.bz2 +/qemu-1.5.2.tar.bz2 +/qemu-1.6.0.tar.bz2 +/qemu-1.6.1.tar.bz2 +/qemu-1.7.0-rc1.tar.bz2 +/qemu-1.7.0.tar.bz2 diff --git a/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch b/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch deleted file mode 100644 index dd83d00..0000000 --- a/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch +++ /dev/null @@ -1,54 +0,0 @@ -From f85faeccdc2b98c4aab0d9781c9650a71a30c23b Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 21:57:47 +0100 -Subject: [PATCH] char: Split out tcp socket close code in a separate function - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 25 ++++++++++++++++--------- - 1 file changed, 16 insertions(+), 9 deletions(-) - -diff --git a/qemu-char.c b/qemu-char.c -index f4a74ac..ac2abeb 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -2155,6 +2155,21 @@ typedef struct { - - static void tcp_chr_accept(void *opaque); - -+static void tcp_closed(void *opaque) -+{ -+ CharDriverState *chr = opaque; -+ TCPCharDriver *s = chr->opaque; -+ -+ s->connected = 0; -+ if (s->listen_fd >= 0) { -+ qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); -+ } -+ qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); -+ closesocket(s->fd); -+ s->fd = -1; -+ qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -+} -+ - static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - TCPCharDriver *s = chr->opaque; -@@ -2316,15 +2331,7 @@ static void tcp_chr_read(void *opaque) - len = s->max_size; - size = tcp_chr_recv(chr, (void *)buf, len); - if (size == 0) { -- /* connection closed */ -- s->connected = 0; -- if (s->listen_fd >= 0) { -- qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); -- } -- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); -- closesocket(s->fd); -- s->fd = -1; -- qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -+ tcp_closed(chr); - } else if (size > 0) { - if (s->do_telnetopt) - tcp_chr_process_IAC_bytes(chr, s, buf, &size); diff --git a/0312-pci-do-not-export-pci_bus_reset.patch b/0001-pci-do-not-export-pci_bus_reset.patch similarity index 70% rename from 0312-pci-do-not-export-pci_bus_reset.patch rename to 0001-pci-do-not-export-pci_bus_reset.patch index 2ce67fd..e23e793 100644 --- a/0312-pci-do-not-export-pci_bus_reset.patch +++ b/0001-pci-do-not-export-pci_bus_reset.patch @@ -1,4 +1,4 @@ -From 5ff013a13ea2530c94ffdfb829f922ba450ddef0 Mon Sep 17 00:00:00 2001 +From 4f9f83c8b0a26a24ab2963e57a375b0ba99638f1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 2 May 2013 11:38:37 +0200 Subject: [PATCH] pci: do not export pci_bus_reset @@ -12,18 +12,17 @@ qbus_reset_all *before* invoking pcibus_reset itself. Tested-by: Claudio Bley Signed-off-by: Paolo Bonzini -Signed-off-by: Cole Robinson --- - hw/pci/pci.c | 8 ++------ - hw/pci/pci.h | 1 - - hw/pci/pci_bridge.c | 2 +- + hw/pci/pci.c | 8 ++------ + hw/pci/pci_bridge.c | 2 +- + include/hw/pci/pci.h | 1 - 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 2f45c8f..5813ef0 100644 +index 49eca95..504ed9d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c -@@ -209,8 +209,9 @@ void pci_device_reset(PCIDevice *dev) +@@ -212,8 +212,9 @@ void pci_device_reset(PCIDevice *dev) * Trigger pci bus reset under a given bus. * To be called on RST# assert. */ @@ -34,7 +33,7 @@ index 2f45c8f..5813ef0 100644 int i; for (i = 0; i < bus->nirq; i++) { -@@ -221,11 +222,6 @@ void pci_bus_reset(PCIBus *bus) +@@ -224,11 +225,6 @@ void pci_bus_reset(PCIBus *bus) pci_device_reset(bus->devices[i]); } } @@ -46,23 +45,11 @@ index 2f45c8f..5813ef0 100644 /* topology traverse is done by pci_bus_reset(). Tell qbus/qdev walker not to traverse the tree */ -diff --git a/hw/pci/pci.h b/hw/pci/pci.h -index f340fe5..b9f2a5a 100644 ---- a/hw/pci/pci.h -+++ b/hw/pci/pci.h -@@ -346,7 +346,6 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus); - void pci_device_set_intx_routing_notifier(PCIDevice *dev, - PCIINTxRoutingNotifier notifier); - void pci_device_reset(PCIDevice *dev); --void pci_bus_reset(PCIBus *bus); - - PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, - const char *default_devaddr); diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c -index 995842a..1b9722e 100644 +index 290abab..41d8755 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c -@@ -234,7 +234,7 @@ void pci_bridge_write_config(PCIDevice *d, +@@ -268,7 +268,7 @@ void pci_bridge_write_config(PCIDevice *d, newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL); if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) { /* Trigger hot reset on 0->1 transition. */ @@ -71,3 +58,15 @@ index 995842a..1b9722e 100644 } } +diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h +index b783e68..754b82d 100644 +--- a/include/hw/pci/pci.h ++++ b/include/hw/pci/pci.h +@@ -373,7 +373,6 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus); + void pci_device_set_intx_routing_notifier(PCIDevice *dev, + PCIINTxRoutingNotifier notifier); + void pci_device_reset(PCIDevice *dev); +-void pci_bus_reset(PCIBus *bus); + + PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus, + const char *default_model, diff --git a/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch b/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch deleted file mode 100644 index e5705e7..0000000 --- a/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch +++ /dev/null @@ -1,1068 +0,0 @@ -From 260acf7f716aa138138dc301b80a1bd10761b0bc Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 20:31:45 +0100 -Subject: [PATCH] char: Add a QemuChrHandlers struct to initialise chardev - handlers - -Instead of passing each handler in the qemu_add_handlers() function, -create a struct of handlers that can be passed to the function instead. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - backends/rng-egd.c | 12 +++++++++--- - gdbstub.c | 9 +++++++-- - hw/cadence_uart.c | 9 +++++++-- - hw/ccid-card-passthru.c | 11 +++++++---- - hw/debugcon.c | 2 +- - hw/escc.c | 9 +++++++-- - hw/etraxfs_ser.c | 13 +++++++++---- - hw/exynos4210_uart.c | 9 +++++++-- - hw/grlib_apbuart.c | 12 +++++++----- - hw/imx_serial.c | 9 +++++++-- - hw/ipoctal232.c | 9 +++++++-- - hw/ivshmem.c | 28 ++++++++++++++++++++++------ - hw/lm32_juart.c | 8 +++++++- - hw/lm32_uart.c | 8 +++++++- - hw/mcf_uart.c | 9 +++++++-- - hw/milkymist-uart.c | 8 +++++++- - hw/pl011.c | 9 +++++++-- - hw/pxa2xx.c | 13 +++++++++---- - hw/qdev-properties-system.c | 2 +- - hw/s390x/sclpconsole.c | 9 +++++++-- - hw/serial.c | 11 ++++++++--- - hw/sh_serial.c | 12 +++++++++--- - hw/spapr_vty.c | 8 ++++++-- - hw/strongarm.c | 12 +++++++----- - hw/usb/dev-serial.c | 11 ++++++++--- - hw/usb/redirect.c | 9 +++++++-- - hw/virtio-console.c | 9 +++++++-- - hw/xen_console.c | 16 +++++++++++----- - hw/xilinx_uartlite.c | 11 +++++++++-- - include/char/char.h | 13 +++++++++---- - monitor.c | 18 ++++++++++++++---- - net/slirp.c | 8 ++++++-- - qemu-char.c | 32 ++++++++++++++++++++++---------- - qtest.c | 9 ++++++++- - 34 files changed, 280 insertions(+), 97 deletions(-) - -diff --git a/backends/rng-egd.c b/backends/rng-egd.c -index 5e012e9..b09876a 100644 ---- a/backends/rng-egd.c -+++ b/backends/rng-egd.c -@@ -133,6 +133,13 @@ static void rng_egd_cancel_requests(RngBackend *b) - rng_egd_free_requests(s); - } - -+static const QemuChrHandlers rng_egd_handlers = { -+ .fd_can_read = rng_egd_chr_can_read, -+ .fd_read = rng_egd_chr_read, -+ .fd_event = NULL, -+}; -+ -+ - static void rng_egd_opened(RngBackend *b, Error **errp) - { - RngEgd *s = RNG_EGD(b); -@@ -150,8 +157,7 @@ static void rng_egd_opened(RngBackend *b, Error **errp) - } - - /* FIXME we should resubmit pending requests when the CDS reconnects. */ -- qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read, -- NULL, s); -+ qemu_chr_add_handlers(s->chr, &rng_egd_handlers, s); - } - - static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp) -@@ -190,7 +196,7 @@ static void rng_egd_finalize(Object *obj) - RngEgd *s = RNG_EGD(obj); - - if (s->chr) { -- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL); -+ qemu_chr_add_handlers(s->chr, NULL, NULL); - } - - g_free(s->chr_name); -diff --git a/gdbstub.c b/gdbstub.c -index 6cd26f1..2da07e9 100644 ---- a/gdbstub.c -+++ b/gdbstub.c -@@ -2992,6 +2992,12 @@ static void gdb_sigterm_handler(int signal) - } - #endif - -+static const QemuChrHandlers gdb_handlers = { -+ .fd_can_read = gdb_chr_can_receive, -+ .fd_read = gdb_chr_receive, -+ .fd_event = gdb_chr_event, -+}; -+ - int gdbserver_start(const char *device) - { - GDBState *s; -@@ -3021,8 +3027,7 @@ int gdbserver_start(const char *device) - if (!chr) - return -1; - -- qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive, -- gdb_chr_event, NULL); -+ qemu_chr_add_handlers(chr, &gdb_handlers, NULL); - } - - s = gdbserver_state; -diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c -index 5766d38..dd1a7d6 100644 ---- a/hw/cadence_uart.c -+++ b/hw/cadence_uart.c -@@ -439,6 +439,12 @@ static void cadence_uart_reset(UartState *s) - s->rx_wpos = 0; - } - -+static const QemuChrHandlers cadence_uart_handlers = { -+ .fd_can_read = uart_can_receive, -+ .fd_read = uart_receive, -+ .fd_event = uart_event, -+}; -+ - static int cadence_uart_init(SysBusDevice *dev) - { - UartState *s = FROM_SYSBUS(UartState, dev); -@@ -460,8 +466,7 @@ static int cadence_uart_init(SysBusDevice *dev) - cadence_uart_reset(s); - - if (s->chr) { -- qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive, -- uart_event, s); -+ qemu_chr_add_handlers(s->chr, &cadence_uart_handlers, s); - } - - return 0; -diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c -index 984bd0b..0dde761 100644 ---- a/hw/ccid-card-passthru.c -+++ b/hw/ccid-card-passthru.c -@@ -274,6 +274,12 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len) - return card->atr; - } - -+static const QemuChrHandlers passthru_handlers = { -+ .fd_can_read = ccid_card_vscard_can_read, -+ .fd_read = ccid_card_vscard_read, -+ .fd_event = ccid_card_vscard_event, -+}; -+ - static int passthru_initfn(CCIDCardState *base) - { - PassthruState *card = DO_UPCAST(PassthruState, base, base); -@@ -282,10 +288,7 @@ static int passthru_initfn(CCIDCardState *base) - card->vscard_in_hdr = 0; - if (card->cs) { - DPRINTF(card, D_INFO, "initing chardev\n"); -- qemu_chr_add_handlers(card->cs, -- ccid_card_vscard_can_read, -- ccid_card_vscard_read, -- ccid_card_vscard_event, card); -+ qemu_chr_add_handlers(card->cs, &passthru_handlers, card); - ccid_card_vscard_send_init(card); - } else { - error_report("missing chardev"); -diff --git a/hw/debugcon.c b/hw/debugcon.c -index 81b2bb0..58e1f90 100644 ---- a/hw/debugcon.c -+++ b/hw/debugcon.c -@@ -88,7 +88,7 @@ static void debugcon_init_core(DebugconState *s) - exit(1); - } - -- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s); -+ qemu_chr_add_handlers(s->chr, NULL, s); - } - - static int debugcon_isa_initfn(ISADevice *dev) -diff --git a/hw/escc.c b/hw/escc.c -index 18c0292..a29784a 100644 ---- a/hw/escc.c -+++ b/hw/escc.c -@@ -867,6 +867,12 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq, - sysbus_mmio_map(s, 0, base); - } - -+static const QemuChrHandlers serial_handlers = { -+ .fd_can_read = serial_can_receive, -+ .fd_read = serial_receive1, -+ .fd_event = serial_event, -+}; -+ - static int escc_init1(SysBusDevice *dev) - { - SerialState *s = FROM_SYSBUS(SerialState, dev); -@@ -879,8 +885,7 @@ static int escc_init1(SysBusDevice *dev) - s->chn[i].chn = 1 - i; - s->chn[i].clock = s->frequency / 2; - if (s->chn[i].chr) { -- qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, -- serial_receive1, serial_event, &s->chn[i]); -+ qemu_chr_add_handlers(s->chn[i].chr, &serial_handlers, &s->chn[i]); - } - } - s->chn[0].otherchn = &s->chn[1]; -diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c -index 72c8868..eb93166 100644 ---- a/hw/etraxfs_ser.c -+++ b/hw/etraxfs_ser.c -@@ -208,6 +208,12 @@ static void etraxfs_ser_reset(DeviceState *d) - - } - -+static const QemuChrHandlers serial_handlers = { -+ .fd_can_read = serial_can_receive, -+ .fd_read = serial_receive, -+ .fd_event = serial_event, -+}; -+ - static int etraxfs_ser_init(SysBusDevice *dev) - { - struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev); -@@ -217,10 +223,9 @@ static int etraxfs_ser_init(SysBusDevice *dev) - sysbus_init_mmio(dev, &s->mmio); - - s->chr = qemu_char_get_next_serial(); -- if (s->chr) -- qemu_chr_add_handlers(s->chr, -- serial_can_receive, serial_receive, -- serial_event, s); -+ if (s->chr) { -+ qemu_chr_add_handlers(s->chr, &serial_handlers, s); -+ } - return 0; - } - -diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c -index bdf797a..8419deb 100644 ---- a/hw/exynos4210_uart.c -+++ b/hw/exynos4210_uart.c -@@ -625,6 +625,12 @@ DeviceState *exynos4210_uart_create(hwaddr addr, - return dev; - } - -+static const QemuChrHandlers exynos4210_handlers = { -+ .fd_can_read = exynos4210_uart_can_receive, -+ .fd_read = exynos4210_uart_receive, -+ .fd_event = exynos4210_uart_event, -+}; -+ - static int exynos4210_uart_init(SysBusDevice *dev) - { - Exynos4210UartState *s = FROM_SYSBUS(Exynos4210UartState, dev); -@@ -636,8 +642,7 @@ static int exynos4210_uart_init(SysBusDevice *dev) - - sysbus_init_irq(dev, &s->irq); - -- qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive, -- exynos4210_uart_receive, exynos4210_uart_event, s); -+ qemu_chr_add_handlers(s->chr, &exynos4210_handlers, s); - - return 0; - } -diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c -index 760bed0..7ede2be 100644 ---- a/hw/grlib_apbuart.c -+++ b/hw/grlib_apbuart.c -@@ -222,15 +222,17 @@ static const MemoryRegionOps grlib_apbuart_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers grlib_handlers = { -+ .fd_can_read = grlib_apbuart_can_receive, -+ .fd_read = grlib_apbuart_receive, -+ .fd_event = grlib_apbuart_event, -+}; -+ - static int grlib_apbuart_init(SysBusDevice *dev) - { - UART *uart = FROM_SYSBUS(typeof(*uart), dev); - -- qemu_chr_add_handlers(uart->chr, -- grlib_apbuart_can_receive, -- grlib_apbuart_receive, -- grlib_apbuart_event, -- uart); -+ qemu_chr_add_handlers(uart->chr, &grlib_handlers, uart); - - sysbus_init_irq(dev, &uart->irq); - -diff --git a/hw/imx_serial.c b/hw/imx_serial.c -index 2d8253e..b0401a1 100644 ---- a/hw/imx_serial.c -+++ b/hw/imx_serial.c -@@ -381,6 +381,12 @@ static const struct MemoryRegionOps imx_serial_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers imx_handlers = { -+ .fd_can_read = imx_can_receive, -+ .fd_read = imx_receive, -+ .fd_event = imx_event, -+}; -+ - static int imx_serial_init(SysBusDevice *dev) - { - IMXSerialState *s = FROM_SYSBUS(IMXSerialState, dev); -@@ -391,8 +397,7 @@ static int imx_serial_init(SysBusDevice *dev) - sysbus_init_irq(dev, &s->irq); - - if (s->chr) { -- qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive, -- imx_event, s); -+ qemu_chr_add_handlers(s->chr, &imx_handlers, s); - } else { - DPRINTF("No char dev for uart at 0x%lx\n", - (unsigned long)s->iomem.ram_addr); -diff --git a/hw/ipoctal232.c b/hw/ipoctal232.c -index c1e3b19..9d1eacf 100644 ---- a/hw/ipoctal232.c -+++ b/hw/ipoctal232.c -@@ -535,6 +535,12 @@ static void hostdev_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers ipoctal_chr_handlers = { -+ .fd_can_read = hostdev_can_receive, -+ .fd_read = hostdev_receive, -+ .fd_event = hostdev_event, -+}; -+ - static int ipoctal_init(IPackDevice *ip) - { - IPOctalState *s = IPOCTAL(ip); -@@ -556,8 +562,7 @@ static int ipoctal_init(IPackDevice *ip) - - if (ch->dev) { - index++; -- qemu_chr_add_handlers(ch->dev, hostdev_can_receive, -- hostdev_receive, hostdev_event, ch); -+ qemu_chr_add_handlers(ch->dev, &ipoctal_chr_handlers, ch); - DPRINTF("Redirecting channel %u to %s (%s)\n", - i, ch->devpath, label); - } else { -diff --git a/hw/ivshmem.c b/hw/ivshmem.c -index afaf9b3..7577307 100644 ---- a/hw/ivshmem.c -+++ b/hw/ivshmem.c -@@ -278,6 +278,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) { - msix_notify(pdev, entry->vector); - } - -+static const QemuChrHandlers ivshmem_handlers = { -+ .fd_can_read = ivshmem_can_receive, -+ .fd_read = ivshmem_receive, -+ .fd_event = ivshmem_event, -+}; -+ -+static const QemuChrHandlers ivshmem_msi_handlers = { -+ .fd_can_read = ivshmem_can_receive, -+ .fd_read = fake_irqfd, -+ .fd_event = ivshmem_event, -+}; -+ - static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *n, - int vector) - { -@@ -298,11 +310,10 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier * - s->eventfd_table[vector].pdev = &s->dev; - s->eventfd_table[vector].vector = vector; - -- qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd, -- ivshmem_event, &s->eventfd_table[vector]); -+ qemu_chr_add_handlers(chr, &ivshmem_msi_handlers, -+ &s->eventfd_table[vector]); - } else { -- qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive, -- ivshmem_event, s); -+ qemu_chr_add_handlers(chr, &ivshmem_handlers, s); - } - - return chr; -@@ -636,6 +647,12 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address, - msix_write_config(pci_dev, address, val, len); - } - -+static const QemuChrHandlers ivshmem_server_handlers = { -+ .fd_can_read = ivshmem_can_receive, -+ .fd_read = ivshmem_read, -+ .fd_event = ivshmem_event, -+}; -+ - static int pci_ivshmem_init(PCIDevice *dev) - { - IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); -@@ -726,8 +743,7 @@ static int pci_ivshmem_init(PCIDevice *dev) - - s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *)); - -- qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read, -- ivshmem_event, s); -+ qemu_chr_add_handlers(s->server_chr, &ivshmem_server_handlers, s); - } else { - /* just map the file immediately, we're not using a server */ - int fd; -diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c -index 8c82c85..840f588 100644 ---- a/hw/lm32_juart.c -+++ b/hw/lm32_juart.c -@@ -110,13 +110,19 @@ static void juart_reset(DeviceState *d) - s->jrx = 0; - } - -+static const QemuChrHandlers juart_handlers = { -+ .fd_can_read = juart_can_rx, -+ .fd_read = juart_rx, -+ .fd_event = juart_event, -+}; -+ - static int lm32_juart_init(SysBusDevice *dev) - { - LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev); - - s->chr = qemu_char_get_next_serial(); - if (s->chr) { -- qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s); -+ qemu_chr_add_handlers(s->chr, &juart_handlers, s); - } - - return 0; -diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c -index 9c89cca..19cfd01 100644 ---- a/hw/lm32_uart.c -+++ b/hw/lm32_uart.c -@@ -243,6 +243,12 @@ static void uart_reset(DeviceState *d) - s->regs[R_LSR] = LSR_THRE | LSR_TEMT; - } - -+static const QemuChrHandlers uart_handlers = { -+ .fd_can_read = uart_can_rx, -+ .fd_read = uart_rx, -+ .fd_event = uart_event, -+}; -+ - static int lm32_uart_init(SysBusDevice *dev) - { - LM32UartState *s = FROM_SYSBUS(typeof(*s), dev); -@@ -254,7 +260,7 @@ static int lm32_uart_init(SysBusDevice *dev) - - s->chr = qemu_char_get_next_serial(); - if (s->chr) { -- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); -+ qemu_chr_add_handlers(s->chr, &uart_handlers, s); - } - - return 0; -diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c -index c443443..fc491f1 100644 ---- a/hw/mcf_uart.c -+++ b/hw/mcf_uart.c -@@ -272,6 +272,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size) - mcf_uart_push_byte(s, buf[0]); - } - -+static const QemuChrHandlers mcf_uart_handlers = { -+ .fd_can_read = mcf_uart_can_receive, -+ .fd_read = mcf_uart_receive, -+ .fd_event = mcf_uart_event, -+}; -+ - void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) - { - mcf_uart_state *s; -@@ -280,8 +286,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) - s->chr = chr; - s->irq = irq; - if (chr) { -- qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive, -- mcf_uart_event, s); -+ qemu_chr_add_handlers(chr, &mcf_uart_handlers, s); - } - mcf_uart_reset(s); - return s; -diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c -index e73eb84..3e03c5c 100644 ---- a/hw/milkymist-uart.c -+++ b/hw/milkymist-uart.c -@@ -189,6 +189,12 @@ static void milkymist_uart_reset(DeviceState *d) - s->regs[R_STAT] = STAT_THRE; - } - -+static const QemuChrHandlers uart_handlers = { -+ .fd_can_read = uart_can_rx, -+ .fd_read = uart_rx, -+ .fd_event = uart_event, -+}; -+ - static int milkymist_uart_init(SysBusDevice *dev) - { - MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev); -@@ -201,7 +207,7 @@ static int milkymist_uart_init(SysBusDevice *dev) - - s->chr = qemu_char_get_next_serial(); - if (s->chr) { -- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); -+ qemu_chr_add_handlers(s->chr, &uart_handlers, s); - } - - return 0; -diff --git a/hw/pl011.c b/hw/pl011.c -index 002a50e..3224bc9 100644 ---- a/hw/pl011.c -+++ b/hw/pl011.c -@@ -261,6 +261,12 @@ static const VMStateDescription vmstate_pl011 = { - } - }; - -+static const QemuChrHandlers pl011_handlers = { -+ .fd_can_read = pl011_can_receive, -+ .fd_read = pl011_receive, -+ .fd_event = pl011_event, -+}; -+ - static int pl011_init(SysBusDevice *dev, const unsigned char *id) - { - pl011_state *s = FROM_SYSBUS(pl011_state, dev); -@@ -276,8 +282,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id) - s->cr = 0x300; - s->flags = 0x90; - if (s->chr) { -- qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, -- pl011_event, s); -+ qemu_chr_add_handlers(s->chr, &pl011_handlers, s); - } - vmstate_register(&dev->qdev, -1, &vmstate_pl011, s); - return 0; -diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c -index d303320..06f43d5 100644 ---- a/hw/pxa2xx.c -+++ b/hw/pxa2xx.c -@@ -1962,6 +1962,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id) - return 0; - } - -+static const QemuChrHandlers pxa2xx_handlers = { -+ .fd_can_read = pxa2xx_fir_is_empty, -+ .fd_read = pxa2xx_fir_rx, -+ .fd_event = pxa2xx_fir_event, -+}; -+ - static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, - hwaddr base, - qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma, -@@ -1980,10 +1986,9 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, - memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000); - memory_region_add_subregion(sysmem, base, &s->iomem); - -- if (chr) -- qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty, -- pxa2xx_fir_rx, pxa2xx_fir_event, s); -- -+ if (chr) { -+ qemu_chr_add_handlers(chr, &pxa2xx_handlers, s); -+ } - register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save, - pxa2xx_fir_load, s); - -diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c -index ce3af22..dd37f58 100644 ---- a/hw/qdev-properties-system.c -+++ b/hw/qdev-properties-system.c -@@ -138,7 +138,7 @@ static void release_chr(Object *obj, const char *name, void *opaque) - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); - - if (*ptr) { -- qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); -+ qemu_chr_add_handlers(*ptr, NULL, NULL); - } - } - -diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c -index effe511..7a77d64 100644 ---- a/hw/s390x/sclpconsole.c -+++ b/hw/s390x/sclpconsole.c -@@ -238,6 +238,12 @@ static void trigger_ascii_console_data(void *env, int n, int level) - sclp_service_interrupt(0); - } - -+static const QemuChrHandlers sclp_chr_handlers = { -+ .fd_can_read = chr_can_read, -+ .fd_read = chr_read, -+ .fd_event = chr_event, -+}; -+ - /* qemu object creation and initialization functions */ - - /* tell character layer our call-back functions */ -@@ -254,8 +260,7 @@ static int console_init(SCLPEvent *event) - console_available = true; - event->event_type = SCLP_EVENT_ASCII_CONSOLE_DATA; - if (scon->chr) { -- qemu_chr_add_handlers(scon->chr, chr_can_read, -- chr_read, chr_event, scon); -+ qemu_chr_add_handlers(scon->chr, &sclp_chr_handlers, scon); - } - scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data, - NULL, 1); -diff --git a/hw/serial.c b/hw/serial.c -index f0ce9b0..589c18a 100644 ---- a/hw/serial.c -+++ b/hw/serial.c -@@ -674,6 +674,12 @@ static void serial_reset(void *opaque) - qemu_irq_lower(s->irq); - } - -+static const QemuChrHandlers serial_handlers = { -+ .fd_can_read = serial_can_receive1, -+ .fd_read = serial_receive1, -+ .fd_event = serial_event, -+}; -+ - void serial_init_core(SerialState *s) - { - if (!s->chr) { -@@ -688,13 +694,12 @@ void serial_init_core(SerialState *s) - - qemu_register_reset(serial_reset, s); - -- qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1, -- serial_event, s); -+ qemu_chr_add_handlers(s->chr, &serial_handlers, s); - } - - void serial_exit_core(SerialState *s) - { -- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL); -+ qemu_chr_add_handlers(s->chr, NULL, NULL); - qemu_unregister_reset(serial_reset, s); - } - -diff --git a/hw/sh_serial.c b/hw/sh_serial.c -index 21c5b13..1cae7e9 100644 ---- a/hw/sh_serial.c -+++ b/hw/sh_serial.c -@@ -352,6 +352,12 @@ static const MemoryRegionOps sh_serial_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers sh_serial_handlers = { -+ .fd_can_read = sh_serial_can_receive1, -+ .fd_read = sh_serial_receive1, -+ .fd_event = sh_serial_event, -+}; -+ - void sh_serial_init(MemoryRegion *sysmem, - hwaddr base, int feat, - uint32_t freq, CharDriverState *chr, -@@ -396,9 +402,9 @@ void sh_serial_init(MemoryRegion *sysmem, - - s->chr = chr; - -- if (chr) -- qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, -- sh_serial_event, s); -+ if (chr) { -+ qemu_chr_add_handlers(chr, &sh_serial_handlers, s); -+ } - - s->eri = eri_source; - s->rxi = rxi_source; -diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c -index 5c63eaa..af2173a 100644 ---- a/hw/spapr_vty.c -+++ b/hw/spapr_vty.c -@@ -54,6 +54,11 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len) - qemu_chr_fe_write(dev->chardev, buf, len); - } - -+static const QemuChrHandlers vty_handlers = { -+ .fd_can_read = vty_can_receive, -+ .fd_read = vty_receive, -+}; -+ - static int spapr_vty_init(VIOsPAPRDevice *sdev) - { - VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev; -@@ -63,8 +68,7 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev) - exit(1); - } - -- qemu_chr_add_handlers(dev->chardev, vty_can_receive, -- vty_receive, NULL, dev); -+ qemu_chr_add_handlers(dev->chardev, &vty_handlers, dev); - - return 0; - } -diff --git a/hw/strongarm.c b/hw/strongarm.c -index ab736e3..9099a06 100644 ---- a/hw/strongarm.c -+++ b/hw/strongarm.c -@@ -1200,6 +1200,12 @@ static const MemoryRegionOps strongarm_uart_ops = { - .endianness = DEVICE_NATIVE_ENDIAN, - }; - -+static const QemuChrHandlers strongarm_uart_handlers = { -+ .fd_can_read = strongarm_uart_can_receive, -+ .fd_read = strongarm_uart_receive, -+ .fd_event = strongarm_uart_event, -+}; -+ - static int strongarm_uart_init(SysBusDevice *dev) - { - StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev); -@@ -1212,11 +1218,7 @@ static int strongarm_uart_init(SysBusDevice *dev) - s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s); - - if (s->chr) { -- qemu_chr_add_handlers(s->chr, -- strongarm_uart_can_receive, -- strongarm_uart_receive, -- strongarm_uart_event, -- s); -+ qemu_chr_add_handlers(s->chr, &strongarm_uart_handlers, s); - } - - return 0; -diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c -index 47ac8c9..2f8757f 100644 ---- a/hw/usb/dev-serial.c -+++ b/hw/usb/dev-serial.c -@@ -414,7 +414,7 @@ static void usb_serial_handle_destroy(USBDevice *dev) - { - USBSerialState *s = (USBSerialState *)dev; - -- qemu_chr_add_handlers(s->cs, NULL, NULL, NULL, NULL); -+ qemu_chr_add_handlers(s->cs, NULL, NULL); - } - - static int usb_serial_can_read(void *opaque) -@@ -478,6 +478,12 @@ static void usb_serial_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers usb_serial_handlers = { -+ .fd_can_read = usb_serial_can_read, -+ .fd_read = usb_serial_read, -+ .fd_event = usb_serial_event, -+}; -+ - static int usb_serial_initfn(USBDevice *dev) - { - USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev); -@@ -491,8 +497,7 @@ static int usb_serial_initfn(USBDevice *dev) - return -1; - } - -- qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read, -- usb_serial_event, s); -+ qemu_chr_add_handlers(s->cs, &usb_serial_handlers, s); - usb_serial_handle_reset(dev); - - if (s->cs->opened && !dev->attached) { -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 1406e3f..2ee9ad1 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -1227,6 +1227,12 @@ static void usbredir_chardev_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers usbredir_chr_handlers = { -+ .fd_can_read = usbredir_chardev_can_read, -+ .fd_read = usbredir_chardev_read, -+ .fd_event = usbredir_chardev_event, -+}; -+ - /* - * init + destroy - */ -@@ -1288,8 +1294,7 @@ static int usbredir_initfn(USBDevice *udev) - - /* Let the backend know we are ready */ - qemu_chr_fe_open(dev->cs); -- qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read, -- usbredir_chardev_read, usbredir_chardev_event, dev); -+ qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev); - - qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev); - add_boot_device_path(dev->bootindex, &udev->qdev, NULL); -diff --git a/hw/virtio-console.c b/hw/virtio-console.c -index 46072a0..dd6f614 100644 ---- a/hw/virtio-console.c -+++ b/hw/virtio-console.c -@@ -106,6 +106,12 @@ static void chr_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers chr_handlers = { -+ .fd_can_read = chr_can_read, -+ .fd_read = chr_read, -+ .fd_event = chr_event, -+}; -+ - static int virtconsole_initfn(VirtIOSerialPort *port) - { - VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -@@ -117,8 +123,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port) - } - - if (vcon->chr) { -- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -- vcon); -+ qemu_chr_add_handlers(vcon->chr, &chr_handlers, vcon); - } - - return 0; -diff --git a/hw/xen_console.c b/hw/xen_console.c -index 44141f8..db1eea5 100644 ---- a/hw/xen_console.c -+++ b/hw/xen_console.c -@@ -215,6 +215,11 @@ out: - return ret; - } - -+static const QemuChrHandlers xencons_handlers = { -+ .fd_can_read = xencons_can_receive, -+ .fd_read = xencons_receive, -+}; -+ - static int con_initialise(struct XenDevice *xendev) - { - struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); -@@ -241,9 +246,9 @@ static int con_initialise(struct XenDevice *xendev) - return -1; - - xen_be_bind_evtchn(&con->xendev); -- if (con->chr) -- qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive, -- NULL, con); -+ if (con->chr) { -+ qemu_chr_add_handlers(con->chr, &xencons_handlers, con); -+ } - - xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n", - con->ring_ref, -@@ -260,8 +265,9 @@ static void con_disconnect(struct XenDevice *xendev) - if (!xendev->dev) { - return; - } -- if (con->chr) -- qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL); -+ if (con->chr) { -+ qemu_chr_add_handlers(con->chr, NULL, NULL); -+ } - xen_be_unbind_evtchn(&con->xendev); - - if (con->sring) { -diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c -index 9963982..f5e4cde 100644 ---- a/hw/xilinx_uartlite.c -+++ b/hw/xilinx_uartlite.c -@@ -192,6 +192,12 @@ static void uart_event(void *opaque, int event) - - } - -+static const QemuChrHandlers uart_handlers = { -+ .fd_can_read = uart_can_rx, -+ .fd_read = uart_rx, -+ .fd_event = uart_event, -+}; -+ - static int xilinx_uartlite_init(SysBusDevice *dev) - { - struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev); -@@ -204,8 +210,9 @@ static int xilinx_uartlite_init(SysBusDevice *dev) - sysbus_init_mmio(dev, &s->mmio); - - s->chr = qemu_char_get_next_serial(); -- if (s->chr) -- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); -+ if (s->chr) { -+ qemu_chr_add_handlers(s->chr, &uart_handlers, s); -+ } - return 0; - } - -diff --git a/include/char/char.h b/include/char/char.h -index c91ce3c..3027cc1 100644 ---- a/include/char/char.h -+++ b/include/char/char.h -@@ -225,10 +225,15 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); - */ - void qemu_chr_be_event(CharDriverState *s, int event); - --void qemu_chr_add_handlers(CharDriverState *s, -- IOCanReadHandler *fd_can_read, -- IOReadHandler *fd_read, -- IOEventHandler *fd_event, -+ -+typedef struct QemuChrHandlers { -+ IOCanReadHandler *fd_can_read; -+ IOReadHandler *fd_read; -+ IOHandler *fd_write_unblocked; -+ IOEventHandler *fd_event; -+} QemuChrHandlers; -+ -+void qemu_chr_add_handlers(CharDriverState *s, const QemuChrHandlers *handlers, - void *opaque); - - void qemu_chr_generic_open(CharDriverState *s); -diff --git a/monitor.c b/monitor.c -index 20bd19b..be83dd6 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -4701,6 +4701,18 @@ static void sortcmdlist(void) - * End: - */ - -+static const QemuChrHandlers monitor_handlers = { -+ .fd_can_read = monitor_can_read, -+ .fd_read = monitor_read, -+ .fd_event = monitor_event, -+}; -+ -+static const QemuChrHandlers monitor_control_handlers = { -+ .fd_can_read = monitor_can_read, -+ .fd_read = monitor_control_read, -+ .fd_event = monitor_control_event, -+}; -+ - void monitor_init(CharDriverState *chr, int flags) - { - static int is_first_init = 1; -@@ -4723,14 +4735,12 @@ void monitor_init(CharDriverState *chr, int flags) - if (monitor_ctrl_mode(mon)) { - mon->mc = g_malloc0(sizeof(MonitorControl)); - /* Control mode requires special handlers */ -- qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read, -- monitor_control_event, mon); -+ qemu_chr_add_handlers(chr, &monitor_control_handlers, mon); - qemu_chr_fe_set_echo(chr, true); - - json_message_parser_init(&mon->mc->parser, handle_qmp_command); - } else { -- qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, -- monitor_event, mon); -+ qemu_chr_add_handlers(chr, &monitor_handlers, mon); - } - - QLIST_INSERT_HEAD(&mon_list, mon, entry); -diff --git a/net/slirp.c b/net/slirp.c -index 4df550f..2868229 100644 ---- a/net/slirp.c -+++ b/net/slirp.c -@@ -595,6 +595,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size) - slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size); - } - -+static const QemuChrHandlers guestfwd_handlers = { -+ .fd_can_read = guestfwd_can_read, -+ .fd_read = guestfwd_read, -+}; -+ - static int slirp_guestfwd(SlirpState *s, const char *config_str, - int legacy_format) - { -@@ -660,8 +665,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, - fwd->port = port; - fwd->slirp = s->slirp; - -- qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read, -- NULL, fwd); -+ qemu_chr_add_handlers(fwd->hd, &guestfwd_handlers, fwd); - } - return 0; - -diff --git a/qemu-char.c b/qemu-char.c -index ac2abeb..0c97bdf 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -192,19 +192,26 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) - va_end(ap); - } - -+static const QemuChrHandlers null_handlers = { -+ /* All handlers are initialised to NULL */ -+}; -+ - void qemu_chr_add_handlers(CharDriverState *s, -- IOCanReadHandler *fd_can_read, -- IOReadHandler *fd_read, -- IOEventHandler *fd_event, -- void *opaque) -+ const QemuChrHandlers *handlers, void *opaque) - { -- if (!opaque && !fd_can_read && !fd_read && !fd_event) { -+ if (!s) { -+ return; -+ } -+ if (!opaque && !handlers) { - /* chr driver being released. */ - ++s->avail_connections; - } -- s->chr_can_read = fd_can_read; -- s->chr_read = fd_read; -- s->chr_event = fd_event; -+ if (!handlers) { -+ handlers = &null_handlers; -+ } -+ s->chr_can_read = handlers->fd_can_read; -+ s->chr_read = handlers->fd_read; -+ s->chr_event = handlers->fd_event; - s->handler_opaque = opaque; - if (s->chr_update_read_handler) - s->chr_update_read_handler(s); -@@ -442,6 +449,12 @@ static void mux_chr_event(void *opaque, int event) - mux_chr_send_event(d, i, event); - } - -+static const QemuChrHandlers mux_chr_handlers = { -+ .fd_can_read = mux_chr_can_read, -+ .fd_read = mux_chr_read, -+ .fd_event = mux_chr_event, -+}; -+ - static void mux_chr_update_read_handler(CharDriverState *chr) - { - MuxDriver *d = chr->opaque; -@@ -456,8 +469,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr) - d->chr_event[d->mux_cnt] = chr->chr_event; - /* Fix up the real driver with mux routines */ - if (d->mux_cnt == 0) { -- qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read, -- mux_chr_event, chr); -+ qemu_chr_add_handlers(d->drv, &mux_chr_handlers, chr); - } - if (d->focus != -1) { - mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); -diff --git a/qtest.c b/qtest.c -index 4663a38..eb8e7ef 100644 ---- a/qtest.c -+++ b/qtest.c -@@ -416,6 +416,13 @@ static void qtest_event(void *opaque, int event) - } - } - -+static const QemuChrHandlers test_handlers = { -+ .fd_can_read = qtest_can_read, -+ .fd_read = qtest_read, -+ .fd_event = qtest_event, -+}; -+ -+ - int qtest_init(void) - { - CharDriverState *chr; -@@ -425,7 +432,7 @@ int qtest_init(void) - configure_icount("0"); - chr = qemu_chr_new("qtest", qtest_chrdev, NULL); - -- qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr); -+ qemu_chr_add_handlers(chr, &test_handlers, chr); - qemu_chr_fe_set_echo(chr, true); - - inbuf = g_string_new(""); diff --git a/0313-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch b/0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch similarity index 86% rename from 0313-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch rename to 0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch index 5b79af2..52e32c4 100644 --- a/0313-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch +++ b/0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch @@ -1,4 +1,4 @@ -From ed7dc4037ba6f105ef2826cf20a8663256e40823 Mon Sep 17 00:00:00 2001 +From 60ab1ca9f2a40610902b610fa0a06fccea7f0f57 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 2 May 2013 11:38:38 +0200 Subject: [PATCH] qdev: allow both pre- and post-order vists in qdev walking @@ -10,41 +10,16 @@ it by adding two extra arguments to the functions. Tested-by: Claudio Bley Signed-off-by: Paolo Bonzini -Signed-off-by: Cole Robinson --- - hw/qdev-core.h | 13 +++++++++---- - hw/qdev.c | 45 +++++++++++++++++++++++++++++++++------------ + hw/core/qdev.c | 45 +++++++++++++++++++++++++++++++++------------ + include/hw/qdev-core.h | 13 +++++++++---- 2 files changed, 42 insertions(+), 16 deletions(-) -diff --git a/hw/qdev-core.h b/hw/qdev-core.h -index cc5bb2a..5dc25ec 100644 ---- a/hw/qdev-core.h -+++ b/hw/qdev-core.h -@@ -237,10 +237,15 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam - /* Returns > 0 if either devfn or busfn skip walk somewhere in cursion, - * < 0 if either devfn or busfn terminate walk somewhere in cursion, - * 0 otherwise. */ --int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, -- qbus_walkerfn *busfn, void *opaque); --int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, -- qbus_walkerfn *busfn, void *opaque); -+int qbus_walk_children(BusState *bus, -+ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn, -+ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn, -+ void *opaque); -+int qdev_walk_children(DeviceState *dev, -+ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn, -+ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn, -+ void *opaque); -+ - void qdev_reset_all(DeviceState *dev); - - /** -diff --git a/hw/qdev.c b/hw/qdev.c -index 1cbd910..50be0f8 100644 ---- a/hw/qdev.c -+++ b/hw/qdev.c -@@ -237,12 +237,12 @@ static int qbus_reset_one(BusState *bus, void *opaque) +diff --git a/hw/core/qdev.c b/hw/core/qdev.c +index e374a93..5ddf1aa 100644 +--- a/hw/core/qdev.c ++++ b/hw/core/qdev.c +@@ -240,12 +240,12 @@ static int qbus_reset_one(BusState *bus, void *opaque) void qdev_reset_all(DeviceState *dev) { @@ -59,7 +34,7 @@ index 1cbd910..50be0f8 100644 } void qbus_reset_all_fn(void *opaque) -@@ -340,49 +340,70 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) +@@ -337,49 +337,70 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) return NULL; } @@ -140,3 +115,27 @@ index 1cbd910..50be0f8 100644 return 0; } +diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h +index f2043a6..ecf5cb3 100644 +--- a/include/hw/qdev-core.h ++++ b/include/hw/qdev-core.h +@@ -253,10 +253,15 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam + /* Returns > 0 if either devfn or busfn skip walk somewhere in cursion, + * < 0 if either devfn or busfn terminate walk somewhere in cursion, + * 0 otherwise. */ +-int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, +- qbus_walkerfn *busfn, void *opaque); +-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, +- qbus_walkerfn *busfn, void *opaque); ++int qbus_walk_children(BusState *bus, ++ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn, ++ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn, ++ void *opaque); ++int qdev_walk_children(DeviceState *dev, ++ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn, ++ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn, ++ void *opaque); ++ + void qdev_reset_all(DeviceState *dev); + + /** diff --git a/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch b/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch deleted file mode 100644 index 7a21103..0000000 --- a/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 1f039120d2d1b4b97dbb92ec84492a7e917ab09e Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 20:32:58 +0100 -Subject: [PATCH] iohandlers: Add enable/disable_write_fd_handler() functions - -These will be used to provide a cleaner API for the nonblocking case. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - include/qemu/main-loop.h | 3 +++ - iohandler.c | 35 +++++++++++++++++++++++++++++++++++ - 2 files changed, 38 insertions(+) - -diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h -index e8059c3..faaf47d 100644 ---- a/include/qemu/main-loop.h -+++ b/include/qemu/main-loop.h -@@ -166,6 +166,9 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); - typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); - typedef int IOCanReadHandler(void *opaque); - -+void enable_write_fd_handler(int fd, IOHandler *fd_write); -+void disable_write_fd_handler(int fd); -+ - /** - * qemu_set_fd_handler2: Register a file descriptor with the main loop - * -diff --git a/iohandler.c b/iohandler.c -index 2523adc..a49cfd4 100644 ---- a/iohandler.c -+++ b/iohandler.c -@@ -45,6 +45,41 @@ typedef struct IOHandlerRecord { - static QLIST_HEAD(, IOHandlerRecord) io_handlers = - QLIST_HEAD_INITIALIZER(io_handlers); - -+static IOHandlerRecord *find_iohandler(int fd) -+{ -+ IOHandlerRecord *ioh; -+ -+ QLIST_FOREACH(ioh, &io_handlers, next) { -+ if (ioh->fd == fd) { -+ return ioh; -+ } -+ } -+ return NULL; -+} -+ -+void enable_write_fd_handler(int fd, IOHandler *fd_write) -+{ -+ IOHandlerRecord *ioh; -+ -+ ioh = find_iohandler(fd); -+ if (!ioh) { -+ return; -+ } -+ -+ ioh->fd_write = fd_write; -+} -+ -+void disable_write_fd_handler(int fd) -+{ -+ IOHandlerRecord *ioh; -+ -+ ioh = find_iohandler(fd); -+ if (!ioh) { -+ return; -+ } -+ -+ ioh->fd_write = NULL; -+} - - /* XXX: fd_read_poll should be suppressed, but an API change is - necessary in the character devices to suppress fd_can_read(). */ diff --git a/0314-qdev-switch-reset-to-post-order.patch b/0003-qdev-switch-reset-to-post-order.patch similarity index 80% rename from 0314-qdev-switch-reset-to-post-order.patch rename to 0003-qdev-switch-reset-to-post-order.patch index d29ee6d..a98f3dd 100644 --- a/0314-qdev-switch-reset-to-post-order.patch +++ b/0003-qdev-switch-reset-to-post-order.patch @@ -1,4 +1,4 @@ -From bca7fa0f8de47d691473257c6d6c9a58ee5d05e8 Mon Sep 17 00:00:00 2001 +From b7906779d6a9eac1815d61cb34aa3d71154025bb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 2 May 2013 11:38:39 +0200 Subject: [PATCH] qdev: switch reset to post-order @@ -25,27 +25,53 @@ which used and still uses pci_device_reset. Tested-by: Claudio Bley Signed-off-by: Paolo Bonzini -Signed-off-by: Cole Robinson --- - hw/pci/pci.c | 31 ++++++++++++++++--------------- - hw/qdev-core.h | 2 +- - hw/qdev.c | 6 +++--- + hw/core/qdev.c | 6 +++--- + hw/pci/pci.c | 31 ++++++++++++++++--------------- + include/hw/qdev-core.h | 2 +- 3 files changed, 20 insertions(+), 19 deletions(-) +diff --git a/hw/core/qdev.c b/hw/core/qdev.c +index 5ddf1aa..d2ffe35 100644 +--- a/hw/core/qdev.c ++++ b/hw/core/qdev.c +@@ -233,19 +233,19 @@ static int qbus_reset_one(BusState *bus, void *opaque) + { + BusClass *bc = BUS_GET_CLASS(bus); + if (bc->reset) { +- return bc->reset(bus); ++ bc->reset(bus); + } + return 0; + } + + void qdev_reset_all(DeviceState *dev) + { +- qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); ++ qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL); + } + + void qbus_reset_all(BusState *bus) + { +- qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); ++ qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL); + } + + void qbus_reset_all_fn(void *opaque) diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 5813ef0..9826b6e 100644 +index 504ed9d..8806636 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c -@@ -45,7 +45,7 @@ +@@ -46,7 +46,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *pcibus_get_dev_path(DeviceState *dev); static char *pcibus_get_fw_dev_path(DeviceState *dev); -static int pcibus_reset(BusState *qbus); +static void pcibus_reset(BusState *qbus); + static void pci_bus_finalize(Object *obj); static Property pci_props[] = { - DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), -@@ -164,16 +164,10 @@ void pci_device_deassert_intx(PCIDevice *dev) +@@ -167,16 +167,10 @@ void pci_device_deassert_intx(PCIDevice *dev) } } @@ -63,7 +89,7 @@ index 5813ef0..9826b6e 100644 dev->irq_state = 0; pci_update_irq_status(dev); pci_device_deassert_intx(dev); -@@ -206,10 +200,21 @@ void pci_device_reset(PCIDevice *dev) +@@ -209,10 +203,21 @@ void pci_device_reset(PCIDevice *dev) } /* @@ -87,7 +113,7 @@ index 5813ef0..9826b6e 100644 { PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus); int i; -@@ -219,13 +224,9 @@ static int pcibus_reset(BusState *qbus) +@@ -222,13 +227,9 @@ static int pcibus_reset(BusState *qbus) } for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { if (bus->devices[i]) { @@ -101,12 +127,12 @@ index 5813ef0..9826b6e 100644 - return 1; } - static void pci_host_bus_register(int domain, PCIBus *bus) -diff --git a/hw/qdev-core.h b/hw/qdev-core.h -index 5dc25ec..083e5ab 100644 ---- a/hw/qdev-core.h -+++ b/hw/qdev-core.h -@@ -144,7 +144,7 @@ struct BusClass { + static void pci_host_bus_register(PCIBus *bus, DeviceState *parent) +diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h +index ecf5cb3..a9ce4a3 100644 +--- a/include/hw/qdev-core.h ++++ b/include/hw/qdev-core.h +@@ -158,7 +158,7 @@ struct BusClass { * bindings can be found at http://playground.sun.com/1275/bindings/. */ char *(*get_fw_dev_path)(DeviceState *dev); @@ -115,30 +141,3 @@ index 5dc25ec..083e5ab 100644 /* maximum devices allowed on the bus, 0: no limit. */ int max_dev; }; -diff --git a/hw/qdev.c b/hw/qdev.c -index 50be0f8..fd2b99e 100644 ---- a/hw/qdev.c -+++ b/hw/qdev.c -@@ -230,19 +230,19 @@ static int qbus_reset_one(BusState *bus, void *opaque) - { - BusClass *bc = BUS_GET_CLASS(bus); - if (bc->reset) { -- return bc->reset(bus); -+ bc->reset(bus); - } - return 0; - } - - void qdev_reset_all(DeviceState *dev) - { -- qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); -+ qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL); - } - - void qbus_reset_all(BusState *bus) - { -- qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); -+ qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL); - } - - void qbus_reset_all_fn(void *opaque) diff --git a/0004-char-Add-framework-for-a-write-unblocked-callback.patch b/0004-char-Add-framework-for-a-write-unblocked-callback.patch deleted file mode 100644 index 57d59cc..0000000 --- a/0004-char-Add-framework-for-a-write-unblocked-callback.patch +++ /dev/null @@ -1,59 +0,0 @@ -From bd1a691c11f718cbd6018a8ef5077c47a2e6d883 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 21:41:42 +0100 -Subject: [PATCH] char: Add framework for a 'write unblocked' callback - -The char layer can let users know that the driver will block on further -input. For users interested in not blocking, they can assign a function -pointer that will be called back when the driver becomes writable. This -patch just adds the function pointers to the CharDriverState structure, -future patches will enable the nonblocking and callback functionality. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - include/char/char.h | 4 ++++ - qemu-char.c | 3 +++ - 2 files changed, 7 insertions(+) - -diff --git a/include/char/char.h b/include/char/char.h -index 3027cc1..2fee107 100644 ---- a/include/char/char.h -+++ b/include/char/char.h -@@ -63,6 +63,9 @@ struct CharDriverState { - IOEventHandler *chr_event; - IOCanReadHandler *chr_can_read; - IOReadHandler *chr_read; -+ IOHandler *chr_write_unblocked; -+ void (*chr_enable_write_fd_handler)(struct CharDriverState *chr); -+ void (*chr_disable_write_fd_handler)(struct CharDriverState *chr); - void *handler_opaque; - void (*chr_close)(struct CharDriverState *chr); - void (*chr_accept_input)(struct CharDriverState *chr); -@@ -76,6 +79,7 @@ struct CharDriverState { - int opened; - int avail_connections; - QemuOpts *opts; -+ bool write_blocked; /* Are we in a blocked state? */ - QTAILQ_ENTRY(CharDriverState) next; - }; - -diff --git a/qemu-char.c b/qemu-char.c -index 0c97bdf..ab0c552 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -211,11 +211,14 @@ void qemu_chr_add_handlers(CharDriverState *s, - } - s->chr_can_read = handlers->fd_can_read; - s->chr_read = handlers->fd_read; -+ s->chr_write_unblocked = handlers->fd_write_unblocked; - s->chr_event = handlers->fd_event; - s->handler_opaque = opaque; - if (s->chr_update_read_handler) - s->chr_update_read_handler(s); - -+ s->write_blocked = false; -+ - /* We're connecting to an already opened device, so let's make sure we - also get the open event */ - if (s->opened) { diff --git a/0004-virtio-bus-remove-vdev-field.patch b/0004-virtio-bus-remove-vdev-field.patch new file mode 100644 index 0000000..b2823f5 --- /dev/null +++ b/0004-virtio-bus-remove-vdev-field.patch @@ -0,0 +1,248 @@ +From d704692d459a40bd28950e734a57075b0ab87393 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:50 +0200 +Subject: [PATCH] virtio-bus: remove vdev field + +The vdev field is complicated to synchronize. Just access the +BusState's list of children. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-bus.c | 65 +++++++++++++++++++++++++----------------- + hw/virtio/virtio-mmio.c | 9 +++--- + hw/virtio/virtio-pci.c | 2 +- + include/hw/virtio/virtio-bus.h | 16 ++++++++--- + 4 files changed, 57 insertions(+), 35 deletions(-) + +diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c +index e6b103c..17dd06e 100644 +--- a/hw/virtio/virtio-bus.c ++++ b/hw/virtio/virtio-bus.c +@@ -46,8 +46,6 @@ int virtio_bus_plug_device(VirtIODevice *vdev) + VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); + DPRINTF("%s: plug device.\n", qbus->name); + +- bus->vdev = vdev; +- + if (klass->device_plugged != NULL) { + klass->device_plugged(qbus->parent); + } +@@ -58,9 +56,11 @@ int virtio_bus_plug_device(VirtIODevice *vdev) + /* Reset the virtio_bus */ + void virtio_bus_reset(VirtioBusState *bus) + { ++ VirtIODevice *vdev = virtio_bus_get_device(bus); ++ + DPRINTF("%s: reset device.\n", qbus->name); +- if (bus->vdev != NULL) { +- virtio_reset(bus->vdev); ++ if (vdev != NULL) { ++ virtio_reset(vdev); + } + } + +@@ -69,62 +69,71 @@ void virtio_bus_destroy_device(VirtioBusState *bus) + { + BusState *qbus = BUS(bus); + VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); ++ VirtIODevice *vdev = virtio_bus_get_device(bus); ++ + DPRINTF("%s: remove device.\n", qbus->name); + +- if (bus->vdev != NULL) { ++ if (vdev != NULL) { + if (klass->device_unplug != NULL) { + klass->device_unplug(qbus->parent); + } +- object_unparent(OBJECT(bus->vdev)); +- bus->vdev = NULL; ++ object_unparent(OBJECT(vdev)); + } + } + + /* Get the device id of the plugged device. */ + uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus) + { +- assert(bus->vdev != NULL); +- return bus->vdev->device_id; ++ VirtIODevice *vdev = virtio_bus_get_device(bus); ++ assert(vdev != NULL); ++ return vdev->device_id; + } + + /* Get the config_len field of the plugged device. */ + size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus) + { +- assert(bus->vdev != NULL); +- return bus->vdev->config_len; ++ VirtIODevice *vdev = virtio_bus_get_device(bus); ++ assert(vdev != NULL); ++ return vdev->config_len; + } + + /* Get the features of the plugged device. */ + uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus, + uint32_t requested_features) + { ++ VirtIODevice *vdev = virtio_bus_get_device(bus); + VirtioDeviceClass *k; +- assert(bus->vdev != NULL); +- k = VIRTIO_DEVICE_GET_CLASS(bus->vdev); ++ ++ assert(vdev != NULL); ++ k = VIRTIO_DEVICE_GET_CLASS(vdev); + assert(k->get_features != NULL); +- return k->get_features(bus->vdev, requested_features); ++ return k->get_features(vdev, requested_features); + } + + /* Set the features of the plugged device. */ + void virtio_bus_set_vdev_features(VirtioBusState *bus, + uint32_t requested_features) + { ++ VirtIODevice *vdev = virtio_bus_get_device(bus); + VirtioDeviceClass *k; +- assert(bus->vdev != NULL); +- k = VIRTIO_DEVICE_GET_CLASS(bus->vdev); ++ ++ assert(vdev != NULL); ++ k = VIRTIO_DEVICE_GET_CLASS(vdev); + if (k->set_features != NULL) { +- k->set_features(bus->vdev, requested_features); ++ k->set_features(vdev, requested_features); + } + } + + /* Get bad features of the plugged device. */ + uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus) + { ++ VirtIODevice *vdev = virtio_bus_get_device(bus); + VirtioDeviceClass *k; +- assert(bus->vdev != NULL); +- k = VIRTIO_DEVICE_GET_CLASS(bus->vdev); ++ ++ assert(vdev != NULL); ++ k = VIRTIO_DEVICE_GET_CLASS(vdev); + if (k->bad_features != NULL) { +- return k->bad_features(bus->vdev); ++ return k->bad_features(vdev); + } else { + return 0; + } +@@ -133,22 +142,26 @@ uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus) + /* Get config of the plugged device. */ + void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config) + { ++ VirtIODevice *vdev = virtio_bus_get_device(bus); + VirtioDeviceClass *k; +- assert(bus->vdev != NULL); +- k = VIRTIO_DEVICE_GET_CLASS(bus->vdev); ++ ++ assert(vdev != NULL); ++ k = VIRTIO_DEVICE_GET_CLASS(vdev); + if (k->get_config != NULL) { +- k->get_config(bus->vdev, config); ++ k->get_config(vdev, config); + } + } + + /* Set config of the plugged device. */ + void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config) + { ++ VirtIODevice *vdev = virtio_bus_get_device(bus); + VirtioDeviceClass *k; +- assert(bus->vdev != NULL); +- k = VIRTIO_DEVICE_GET_CLASS(bus->vdev); ++ ++ assert(vdev != NULL); ++ k = VIRTIO_DEVICE_GET_CLASS(vdev); + if (k->set_config != NULL) { +- k->set_config(bus->vdev, config); ++ k->set_config(vdev, config); + } + } + +diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c +index 29cf284..8829eb0 100644 +--- a/hw/virtio/virtio-mmio.c ++++ b/hw/virtio/virtio-mmio.c +@@ -95,7 +95,7 @@ static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size, + static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size) + { + VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque; +- VirtIODevice *vdev = proxy->bus.vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + + DPRINTF("virtio_mmio_read offset 0x%x\n", (int)offset); + +@@ -185,7 +185,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) + { + VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque; +- VirtIODevice *vdev = proxy->bus.vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + + DPRINTF("virtio_mmio_write offset 0x%x value 0x%" PRIx64 "\n", + (int)offset, value); +@@ -298,12 +298,13 @@ static const MemoryRegionOps virtio_mem_ops = { + static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector) + { + VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int level; + +- if (!proxy->bus.vdev) { ++ if (!vdev) { + return; + } +- level = (proxy->bus.vdev->isr != 0); ++ level = (vdev->isr != 0); + DPRINTF("virtio_mmio setting IRQ %d\n", level); + qemu_set_irq(proxy->irq, level); + } +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index 7647be8..76b7652 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -943,7 +943,7 @@ static void virtio_pci_device_plugged(DeviceState *d) + uint8_t *config; + uint32_t size; + +- proxy->vdev = bus->vdev; ++ proxy->vdev = virtio_bus_get_device(bus); + + config = proxy->pci_dev.config; + if (proxy->class_code) { +diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h +index 9217f85..ba0f86a 100644 +--- a/include/hw/virtio/virtio-bus.h ++++ b/include/hw/virtio/virtio-bus.h +@@ -72,10 +72,6 @@ typedef struct VirtioBusClass { + + struct VirtioBusState { + BusState parent_obj; +- /* +- * Only one VirtIODevice can be plugged on the bus. +- */ +- VirtIODevice *vdev; + }; + + int virtio_bus_plug_device(VirtIODevice *vdev); +@@ -98,4 +94,16 @@ void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config); + /* Set config of the plugged device. */ + void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config); + ++static inline VirtIODevice *virtio_bus_get_device(VirtioBusState *bus) ++{ ++ BusState *qbus = &bus->parent_obj; ++ BusChild *kid = QTAILQ_FIRST(&qbus->children); ++ DeviceState *qdev = kid ? kid->child : NULL; ++ ++ /* This is used on the data path, the cast is guaranteed ++ * to succeed by the qdev machinery. ++ */ ++ return (VirtIODevice *)qdev; ++} ++ + #endif /* VIRTIO_BUS_H */ diff --git a/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch b/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch deleted file mode 100644 index 76114f4..0000000 --- a/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch +++ /dev/null @@ -1,178 +0,0 @@ -From c2dfb673b44dc776109b6c1a9f6a3e28b3e32cf4 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 22:00:27 +0100 -Subject: [PATCH] char: Update send_all() to handle nonblocking chardev write - requests - -The send_all function is modified to return to the caller in case the -driver cannot handle any more data. It returns -EAGAIN or -WSAEWOULDBLOCK on non-Windows and Windows platforms respectively. This -is only done when the caller sets a callback function handler indicating -it's not interested in blocking till the driver has written out all the -data. - -Currently there's no driver or caller that supports this. Future -commits will add such capability. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - include/qemu/sockets.h | 3 ++- - qemu-char.c | 69 +++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 65 insertions(+), 7 deletions(-) - -diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h -index 0ccf32f..42ca690 100644 ---- a/include/qemu/sockets.h -+++ b/include/qemu/sockets.h -@@ -29,6 +29,7 @@ int inet_aton(const char *cp, struct in_addr *ia); - #include "qemu/option.h" - #include "qapi/error.h" - #include "qapi/qmp/qerror.h" -+#include "char/char.h" - - /* misc helpers */ - int qemu_socket(int domain, int type, int protocol); -@@ -36,7 +37,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); - int socket_set_cork(int fd, int v); - void qemu_set_block(int fd); - void qemu_set_nonblock(int fd); --int send_all(int fd, const void *buf, int len1); -+int send_all(CharDriverState *chr, int fd, const void *buf, int len1); - - /* callback function for nonblocking connect - * valid fd on success, negative error code on failure -diff --git a/qemu-char.c b/qemu-char.c -index ab0c552..96fc54e 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -508,7 +508,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) - - - #ifdef _WIN32 --int send_all(int fd, const void *buf, int len1) -+static int do_send(int fd, const void *buf, int len1, bool nonblock) - { - int ret, len; - -@@ -516,9 +516,14 @@ int send_all(int fd, const void *buf, int len1) - while (len > 0) { - ret = send(fd, buf, len, 0); - if (ret < 0) { -+ if (nonblock && len1 - len) { -+ return len1 - len; -+ } - errno = WSAGetLastError(); - if (errno != WSAEWOULDBLOCK) { - return -1; -+ } else if (errno == WSAEWOULDBLOCK && nonblock) { -+ return WSAEWOULDBLOCK; - } - } else if (ret == 0) { - break; -@@ -532,7 +537,7 @@ int send_all(int fd, const void *buf, int len1) - - #else - --int send_all(int fd, const void *_buf, int len1) -+static int do_send(int fd, const void *_buf, int len1, bool nonblock) - { - int ret, len; - const uint8_t *buf = _buf; -@@ -541,8 +546,15 @@ int send_all(int fd, const void *_buf, int len1) - while (len > 0) { - ret = write(fd, buf, len); - if (ret < 0) { -- if (errno != EINTR && errno != EAGAIN) -+ if (nonblock && len1 - len) { -+ return len1 - len; -+ } -+ if (errno == EAGAIN && nonblock) { -+ return -EAGAIN; -+ } -+ if (errno != EINTR && errno != EAGAIN) { - return -1; -+ } - } else if (ret == 0) { - break; - } else { -@@ -557,6 +569,44 @@ int send_all(int fd, const void *_buf, int len1) - #define STDIO_MAX_CLIENTS 1 - static int stdio_nb_clients; - -+int send_all(CharDriverState *chr, int fd, const void *_buf, int len1) -+{ -+ int ret, eagain_errno; -+ bool nonblock; -+ -+ if (chr && chr->write_blocked) { -+ /* -+ * The caller should not send us data while we're blocked, -+ * but this can happen when multiple writers are woken at once, -+ * so simply return -EAGAIN. -+ */ -+ return -EAGAIN; -+ } -+ -+ nonblock = false; -+ /* -+ * Ensure the char backend is able to receive and handle the -+ * 'write unblocked' event before we turn on nonblock support. -+ */ -+ if (chr && chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) { -+ nonblock = true; -+ } -+ ret = do_send(fd, _buf, len1, nonblock); -+ -+#ifdef _WIN32 -+ eagain_errno = WSAEWOULDBLOCK; -+#else -+ eagain_errno = -EAGAIN; -+#endif -+ -+ if (nonblock && (ret == eagain_errno || (ret >= 0 && ret < len1))) { -+ /* Update fd handler to wake up when chr becomes writable */ -+ chr->chr_enable_write_fd_handler(chr); -+ chr->write_blocked = true; -+ } -+ return ret; -+} -+ - #ifndef _WIN32 - - typedef struct { -@@ -568,7 +618,7 @@ typedef struct { - static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - FDCharDriver *s = chr->opaque; -- return send_all(s->fd_out, buf, len); -+ return send_all(chr, s->fd_out, buf, len); - } - - static int fd_chr_read_poll(void *opaque) -@@ -893,7 +943,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - pty_chr_update_read_handler(chr); - return 0; - } -- return send_all(s->fd, buf, len); -+ return send_all(chr, s->fd, buf, len); - } - - static int pty_chr_read_poll(void *opaque) -@@ -2188,8 +2238,15 @@ static void tcp_closed(void *opaque) - static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - TCPCharDriver *s = chr->opaque; -+ - if (s->connected) { -- return send_all(s->fd, buf, len); -+ int ret; -+ -+ ret = send_all(chr, s->fd, buf, len); -+ if (ret == -1 && errno == EPIPE) { -+ tcp_closed(chr); -+ } -+ return ret; - } else { - /* XXX: indicate an error ? */ - return len; diff --git a/0005-virtio-pci-remove-vdev-field.patch b/0005-virtio-pci-remove-vdev-field.patch new file mode 100644 index 0000000..5e636b4 --- /dev/null +++ b/0005-virtio-pci-remove-vdev-field.patch @@ -0,0 +1,447 @@ +From 3dfc39e3dcdf006d3aef8b8be1f3947f9393b90f Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:51 +0200 +Subject: [PATCH] virtio-pci: remove vdev field + +The vdev field is complicated to synchronize. Just access the +BusState's list of children. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/s390x/virtio-ccw.h | 1 - + hw/virtio/virtio-pci.c | 107 +++++++++++++++++++++++++++++-------------------- + hw/virtio/virtio-pci.h | 1 - + 3 files changed, 63 insertions(+), 46 deletions(-) + +diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h +index 96d6f5d..00932c7 100644 +--- a/hw/s390x/virtio-ccw.h ++++ b/hw/s390x/virtio-ccw.h +@@ -77,7 +77,6 @@ typedef struct VirtIOCCWDeviceClass { + struct VirtioCcwDevice { + DeviceState parent_obj; + SubchDev *sch; +- VirtIODevice *vdev; + char *bus_id; + uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE]; + VirtioBusState bus; +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index 76b7652..be18e92 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -113,31 +113,39 @@ static inline VirtIOPCIProxy *to_virtio_pci_proxy_fast(DeviceState *d) + static void virtio_pci_notify(DeviceState *d, uint16_t vector) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ + if (msix_enabled(&proxy->pci_dev)) + msix_notify(&proxy->pci_dev, vector); + else +- pci_set_irq(&proxy->pci_dev, proxy->vdev->isr & 1); ++ pci_set_irq(&proxy->pci_dev, vdev->isr & 1); + } + + static void virtio_pci_save_config(DeviceState *d, QEMUFile *f) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ + pci_device_save(&proxy->pci_dev, f); + msix_save(&proxy->pci_dev, f); + if (msix_present(&proxy->pci_dev)) +- qemu_put_be16(f, proxy->vdev->config_vector); ++ qemu_put_be16(f, vdev->config_vector); + } + + static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ + if (msix_present(&proxy->pci_dev)) +- qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n)); ++ qemu_put_be16(f, virtio_queue_vector(vdev, n)); + } + + static int virtio_pci_load_config(DeviceState *d, QEMUFile *f) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ + int ret; + ret = pci_device_load(&proxy->pci_dev, f); + if (ret) { +@@ -146,12 +154,12 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f) + msix_unuse_all_vectors(&proxy->pci_dev); + msix_load(&proxy->pci_dev, f); + if (msix_present(&proxy->pci_dev)) { +- qemu_get_be16s(f, &proxy->vdev->config_vector); ++ qemu_get_be16s(f, &vdev->config_vector); + } else { +- proxy->vdev->config_vector = VIRTIO_NO_VECTOR; ++ vdev->config_vector = VIRTIO_NO_VECTOR; + } +- if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) { +- return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector); ++ if (vdev->config_vector != VIRTIO_NO_VECTOR) { ++ return msix_vector_use(&proxy->pci_dev, vdev->config_vector); + } + return 0; + } +@@ -159,13 +167,15 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f) + static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ + uint16_t vector; + if (msix_present(&proxy->pci_dev)) { + qemu_get_be16s(f, &vector); + } else { + vector = VIRTIO_NO_VECTOR; + } +- virtio_queue_set_vector(proxy->vdev, n, vector); ++ virtio_queue_set_vector(vdev, n, vector); + if (vector != VIRTIO_NO_VECTOR) { + return msix_vector_use(&proxy->pci_dev, vector); + } +@@ -175,7 +185,8 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f) + static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy, + int n, bool assign, bool set_handler) + { +- VirtQueue *vq = virtio_get_queue(proxy->vdev, n); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ VirtQueue *vq = virtio_get_queue(vdev, n); + EventNotifier *notifier = virtio_queue_get_host_notifier(vq); + int r = 0; + +@@ -200,6 +211,7 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy, + + static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) + { ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int n, r; + + if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) || +@@ -209,7 +221,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) + } + + for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { +- if (!virtio_queue_get_num(proxy->vdev, n)) { ++ if (!virtio_queue_get_num(vdev, n)) { + continue; + } + +@@ -223,7 +235,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) + + assign_error: + while (--n >= 0) { +- if (!virtio_queue_get_num(proxy->vdev, n)) { ++ if (!virtio_queue_get_num(vdev, n)) { + continue; + } + +@@ -236,6 +248,7 @@ assign_error: + + static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) + { ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int r; + int n; + +@@ -244,7 +257,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) + } + + for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { +- if (!virtio_queue_get_num(proxy->vdev, n)) { ++ if (!virtio_queue_get_num(vdev, n)) { + continue; + } + +@@ -257,7 +270,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) + static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) + { + VirtIOPCIProxy *proxy = opaque; +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + hwaddr pa; + + switch (addr) { +@@ -272,7 +285,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) + pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; + if (pa == 0) { + virtio_pci_stop_ioeventfd(proxy); +- virtio_reset(proxy->vdev); ++ virtio_reset(vdev); + msix_unuse_all_vectors(&proxy->pci_dev); + } + else +@@ -299,7 +312,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) + } + + if (vdev->status == 0) { +- virtio_reset(proxy->vdev); ++ virtio_reset(vdev); + msix_unuse_all_vectors(&proxy->pci_dev); + } + +@@ -335,7 +348,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) + + static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr) + { +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + uint32_t ret = 0xFFFFFFFF; + + switch (addr) { +@@ -381,6 +394,7 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr, + unsigned size) + { + VirtIOPCIProxy *proxy = opaque; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + uint64_t val = 0; + if (addr < config) { +@@ -390,16 +404,16 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr, + + switch (size) { + case 1: +- val = virtio_config_readb(proxy->vdev, addr); ++ val = virtio_config_readb(vdev, addr); + break; + case 2: +- val = virtio_config_readw(proxy->vdev, addr); ++ val = virtio_config_readw(vdev, addr); + if (virtio_is_big_endian()) { + val = bswap16(val); + } + break; + case 4: +- val = virtio_config_readl(proxy->vdev, addr); ++ val = virtio_config_readl(vdev, addr); + if (virtio_is_big_endian()) { + val = bswap32(val); + } +@@ -413,6 +427,7 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr, + { + VirtIOPCIProxy *proxy = opaque; + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + if (addr < config) { + virtio_ioport_write(proxy, addr, val); + return; +@@ -424,19 +439,19 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr, + */ + switch (size) { + case 1: +- virtio_config_writeb(proxy->vdev, addr, val); ++ virtio_config_writeb(vdev, addr, val); + break; + case 2: + if (virtio_is_big_endian()) { + val = bswap16(val); + } +- virtio_config_writew(proxy->vdev, addr, val); ++ virtio_config_writew(vdev, addr, val); + break; + case 4: + if (virtio_is_big_endian()) { + val = bswap32(val); + } +- virtio_config_writel(proxy->vdev, addr, val); ++ virtio_config_writel(vdev, addr, val); + break; + } + } +@@ -455,6 +470,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) + { + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + + pci_default_write_config(pci_dev, address, val, len); + +@@ -462,8 +478,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, + !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) && + !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) { + virtio_pci_stop_ioeventfd(proxy); +- virtio_set_status(proxy->vdev, +- proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK); ++ virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK); + } + } + +@@ -506,7 +521,8 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy, + unsigned int vector) + { + VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; +- VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ VirtQueue *vq = virtio_get_queue(vdev, queue_no); + EventNotifier *n = virtio_queue_get_guest_notifier(vq); + int ret; + ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq); +@@ -517,7 +533,8 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy, + unsigned int queue_no, + unsigned int vector) + { +- VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ VirtQueue *vq = virtio_get_queue(vdev, queue_no); + EventNotifier *n = virtio_queue_get_guest_notifier(vq); + VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; + int ret; +@@ -529,7 +546,7 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy, + static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) + { + PCIDevice *dev = &proxy->pci_dev; +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + unsigned int vector; + int ret, queue_no; +@@ -578,7 +595,7 @@ undo: + static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) + { + PCIDevice *dev = &proxy->pci_dev; +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + unsigned int vector; + int queue_no; + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); +@@ -606,8 +623,9 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, + unsigned int vector, + MSIMessage msg) + { +- VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev); +- VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); ++ VirtQueue *vq = virtio_get_queue(vdev, queue_no); + EventNotifier *n = virtio_queue_get_guest_notifier(vq); + VirtIOIRQFD *irqfd; + int ret = 0; +@@ -626,10 +644,10 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, + * Otherwise, set it up now. + */ + if (k->guest_notifier_mask) { +- k->guest_notifier_mask(proxy->vdev, queue_no, false); ++ k->guest_notifier_mask(vdev, queue_no, false); + /* Test after unmasking to avoid losing events. */ + if (k->guest_notifier_pending && +- k->guest_notifier_pending(proxy->vdev, queue_no)) { ++ k->guest_notifier_pending(vdev, queue_no)) { + event_notifier_set(n); + } + } else { +@@ -642,13 +660,14 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, + unsigned int queue_no, + unsigned int vector) + { +- VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + + /* If guest supports masking, keep irqfd but mask it. + * Otherwise, clean it up now. + */ + if (k->guest_notifier_mask) { +- k->guest_notifier_mask(proxy->vdev, queue_no, true); ++ k->guest_notifier_mask(vdev, queue_no, true); + } else { + kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); + } +@@ -658,7 +677,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, + MSIMessage msg) + { + VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int ret, queue_no; + + for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { +@@ -688,7 +707,7 @@ undo: + static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) + { + VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int queue_no; + + for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { +@@ -707,7 +726,7 @@ static void virtio_pci_vector_poll(PCIDevice *dev, + unsigned int vector_end) + { + VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + int queue_no; + unsigned int vector; +@@ -739,8 +758,9 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, + bool with_irqfd) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); +- VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(proxy->vdev); +- VirtQueue *vq = virtio_get_queue(proxy->vdev, n); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); ++ VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); ++ VirtQueue *vq = virtio_get_queue(vdev, n); + EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); + + if (assign) { +@@ -755,7 +775,7 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, + } + + if (!msix_enabled(&proxy->pci_dev) && vdc->guest_notifier_mask) { +- vdc->guest_notifier_mask(proxy->vdev, n, !assign); ++ vdc->guest_notifier_mask(vdev, n, !assign); + } + + return 0; +@@ -770,7 +790,7 @@ static bool virtio_pci_query_guest_notifiers(DeviceState *d) + static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); +- VirtIODevice *vdev = proxy->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + int r, n; + bool with_irqfd = msix_enabled(&proxy->pci_dev) && +@@ -864,11 +884,12 @@ static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign) + static void virtio_pci_vmstate_change(DeviceState *d, bool running) + { + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + + if (running) { + /* Try to find out if the guest has bus master disabled, but is + in ready state. Then we have a buggy guest OS. */ +- if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) && ++ if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) && + !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { + proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; + } +@@ -943,8 +964,6 @@ static void virtio_pci_device_plugged(DeviceState *d) + uint8_t *config; + uint32_t size; + +- proxy->vdev = virtio_bus_get_device(bus); +- + config = proxy->pci_dev.config; + if (proxy->class_code) { + pci_config_set_class(config, proxy->class_code); +diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h +index 917bcc5..dc332ae 100644 +--- a/hw/virtio/virtio-pci.h ++++ b/hw/virtio/virtio-pci.h +@@ -82,7 +82,6 @@ typedef struct VirtioPCIClass { + + struct VirtIOPCIProxy { + PCIDevice pci_dev; +- VirtIODevice *vdev; + MemoryRegion bar; + uint32_t flags; + uint32_t class_code; diff --git a/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch b/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch deleted file mode 100644 index f53c382..0000000 --- a/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch +++ /dev/null @@ -1,72 +0,0 @@ -From cf067f179258c741547a792eb7c38542d2574165 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 22:02:47 +0100 -Subject: [PATCH] char: Equip the unix/tcp backend to handle nonblocking - writes# - -Now that the infrastructure is in place to return -EAGAIN to callers, -individual char drivers can set their update_fd_handlers() function to -set or remove an fd's write handler. This handler checks if the driver -became writable. - -A generic callback routine is used for unblocking writes and letting -users of chardevs know that a driver became writable again. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/qemu-char.c b/qemu-char.c -index 96fc54e..53d2c13 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -105,6 +105,19 @@ - static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = - QTAILQ_HEAD_INITIALIZER(chardevs); - -+/* -+ * Generic routine that gets called when chardev becomes writable. -+ * Lets chardev user know it's OK to send more data. -+ */ -+static void char_write_unblocked(void *opaque) -+{ -+ CharDriverState *chr = opaque; -+ -+ chr->write_blocked = false; -+ chr->chr_disable_write_fd_handler(chr); -+ chr->chr_write_unblocked(chr->handler_opaque); -+} -+ - void qemu_chr_be_event(CharDriverState *s, int event) - { - /* Keep track if the char device is open */ -@@ -126,6 +139,9 @@ static void qemu_chr_fire_open_event(void *opaque) - { - CharDriverState *s = opaque; - qemu_chr_be_event(s, CHR_EVENT_OPENED); -+ if (s->write_blocked) { -+ char_write_unblocked(s); -+ } - qemu_free_timer(s->open_timer); - s->open_timer = NULL; - } -@@ -2245,6 +2261,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - ret = send_all(chr, s->fd, buf, len); - if (ret == -1 && errno == EPIPE) { - tcp_closed(chr); -+ -+ if (chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) { -+ /* -+ * Since we haven't written out anything, let's say -+ * we're throttled. This will prevent any output from -+ * the guest getting lost if host-side chardev goes -+ * down. Unthrottle when we re-connect. -+ */ -+ chr->write_blocked = true; -+ return 0; -+ } - } - return ret; - } else { diff --git a/0006-virtio-ccw-remove-vdev-field.patch b/0006-virtio-ccw-remove-vdev-field.patch new file mode 100644 index 0000000..d1244d8 --- /dev/null +++ b/0006-virtio-ccw-remove-vdev-field.patch @@ -0,0 +1,293 @@ +From 6f5e351c3f91e76a70c0684276af8070cfeb07da Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:52 +0200 +Subject: [PATCH] virtio-ccw: remove vdev field + +The vdev field is complicated to synchronize. Just access the +BusState's list of children. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/s390x/virtio-ccw.c | 80 ++++++++++++++++++++++++++++----------------------- + 1 file changed, 44 insertions(+), 36 deletions(-) + +diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c +index f93a81c..8947196 100644 +--- a/hw/s390x/virtio-ccw.c ++++ b/hw/s390x/virtio-ccw.c +@@ -57,9 +57,10 @@ static const TypeInfo virtual_css_bus_info = { + VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch) + { + VirtIODevice *vdev = NULL; ++ VirtioCcwDevice *dev = sch->driver_data; + +- if (sch->driver_data) { +- vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev; ++ if (dev) { ++ vdev = virtio_bus_get_device(&dev->bus); + } + return vdev; + } +@@ -67,7 +68,8 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch) + static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n, + bool assign, bool set_handler) + { +- VirtQueue *vq = virtio_get_queue(dev->vdev, n); ++ VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); ++ VirtQueue *vq = virtio_get_queue(vdev, n); + EventNotifier *notifier = virtio_queue_get_host_notifier(vq); + int r = 0; + SubchDev *sch = dev->sch; +@@ -97,6 +99,7 @@ static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n, + + static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev) + { ++ VirtIODevice *vdev; + int n, r; + + if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) || +@@ -104,8 +107,9 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev) + dev->ioeventfd_started) { + return; + } ++ vdev = virtio_bus_get_device(&dev->bus); + for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { +- if (!virtio_queue_get_num(dev->vdev, n)) { ++ if (!virtio_queue_get_num(vdev, n)) { + continue; + } + r = virtio_ccw_set_guest2host_notifier(dev, n, true, true); +@@ -118,7 +122,7 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev) + + assign_error: + while (--n >= 0) { +- if (!virtio_queue_get_num(dev->vdev, n)) { ++ if (!virtio_queue_get_num(vdev, n)) { + continue; + } + r = virtio_ccw_set_guest2host_notifier(dev, n, false, false); +@@ -132,13 +136,15 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev) + + static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev) + { ++ VirtIODevice *vdev; + int n, r; + + if (!dev->ioeventfd_started) { + return; + } ++ vdev = virtio_bus_get_device(&dev->bus); + for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { +- if (!virtio_queue_get_num(dev->vdev, n)) { ++ if (!virtio_queue_get_num(vdev, n)) { + continue; + } + r = virtio_ccw_set_guest2host_notifier(dev, n, false, false); +@@ -189,7 +195,7 @@ typedef struct VirtioFeatDesc { + static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, + uint16_t index, uint16_t num) + { +- VirtioCcwDevice *dev = sch->driver_data; ++ VirtIODevice *vdev = virtio_ccw_get_vdev(sch); + + if (index > VIRTIO_PCI_QUEUE_MAX) { + return -EINVAL; +@@ -200,23 +206,23 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, + return -EINVAL; + } + +- if (!dev) { ++ if (!vdev) { + return -EINVAL; + } + +- virtio_queue_set_addr(dev->vdev, index, addr); ++ virtio_queue_set_addr(vdev, index, addr); + if (!addr) { +- virtio_queue_set_vector(dev->vdev, index, 0); ++ virtio_queue_set_vector(vdev, index, 0); + } else { + /* Fail if we don't have a big enough queue. */ + /* TODO: Add interface to handle vring.num changing */ +- if (virtio_queue_get_num(dev->vdev, index) > num) { ++ if (virtio_queue_get_num(vdev, index) > num) { + return -EINVAL; + } +- virtio_queue_set_vector(dev->vdev, index, index); ++ virtio_queue_set_vector(vdev, index, index); + } + /* tell notify handler in case of config change */ +- dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX; ++ vdev->config_vector = VIRTIO_PCI_QUEUE_MAX; + return 0; + } + +@@ -230,6 +236,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + hwaddr indicators; + VqConfigBlock vq_config; + VirtioCcwDevice *dev = sch->driver_data; ++ VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); + bool check_len; + int len; + hwaddr hw_len; +@@ -272,7 +279,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + break; + case CCW_CMD_VDEV_RESET: + virtio_ccw_stop_ioeventfd(dev); +- virtio_reset(dev->vdev); ++ virtio_reset(vdev); + ret = 0; + break; + case CCW_CMD_READ_FEAT: +@@ -319,7 +326,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + features.features = ldl_le_phys(ccw.cda); + if (features.index < ARRAY_SIZE(dev->host_features)) { + virtio_bus_set_vdev_features(&dev->bus, features.features); +- dev->vdev->guest_features = features.features; ++ vdev->guest_features = features.features; + } else { + /* + * If the guest supports more feature bits, assert that it +@@ -337,30 +344,30 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + break; + case CCW_CMD_READ_CONF: + if (check_len) { +- if (ccw.count > dev->vdev->config_len) { ++ if (ccw.count > vdev->config_len) { + ret = -EINVAL; + break; + } + } +- len = MIN(ccw.count, dev->vdev->config_len); ++ len = MIN(ccw.count, vdev->config_len); + if (!ccw.cda) { + ret = -EFAULT; + } else { +- virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config); ++ virtio_bus_get_vdev_config(&dev->bus, vdev->config); + /* XXX config space endianness */ +- cpu_physical_memory_write(ccw.cda, dev->vdev->config, len); ++ cpu_physical_memory_write(ccw.cda, vdev->config, len); + sch->curr_status.scsw.count = ccw.count - len; + ret = 0; + } + break; + case CCW_CMD_WRITE_CONF: + if (check_len) { +- if (ccw.count > dev->vdev->config_len) { ++ if (ccw.count > vdev->config_len) { + ret = -EINVAL; + break; + } + } +- len = MIN(ccw.count, dev->vdev->config_len); ++ len = MIN(ccw.count, vdev->config_len); + hw_len = len; + if (!ccw.cda) { + ret = -EFAULT; +@@ -371,9 +378,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + } else { + len = hw_len; + /* XXX config space endianness */ +- memcpy(dev->vdev->config, config, len); ++ memcpy(vdev->config, config, len); + cpu_physical_memory_unmap(config, hw_len, 0, hw_len); +- virtio_bus_set_vdev_config(&dev->bus, dev->vdev->config); ++ virtio_bus_set_vdev_config(&dev->bus, vdev->config); + sch->curr_status.scsw.count = ccw.count - len; + ret = 0; + } +@@ -397,9 +404,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) { + virtio_ccw_stop_ioeventfd(dev); + } +- virtio_set_status(dev->vdev, status); +- if (dev->vdev->status == 0) { +- virtio_reset(dev->vdev); ++ virtio_set_status(vdev, status); ++ if (vdev->status == 0) { ++ virtio_reset(vdev); + } + if (status & VIRTIO_CONFIG_S_DRIVER_OK) { + virtio_ccw_start_ioeventfd(dev); +@@ -463,7 +470,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + ret = -EFAULT; + } else { + vq_config.index = lduw_phys(ccw.cda); +- vq_config.num_max = virtio_queue_get_num(dev->vdev, ++ vq_config.num_max = virtio_queue_get_num(vdev, + vq_config.index); + stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max); + sch->curr_status.scsw.count = ccw.count - sizeof(vq_config); +@@ -495,7 +502,6 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) + sch->driver_data = dev; + dev->sch = sch; + +- dev->vdev = vdev; + dev->indicators = 0; + + /* Initialize subchannel structure. */ +@@ -608,7 +614,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) + memset(&sch->id, 0, sizeof(SenseId)); + sch->id.reserved = 0xff; + sch->id.cu_type = VIRTIO_CCW_CU_TYPE; +- sch->id.cu_model = dev->vdev->device_id; ++ sch->id.cu_model = vdev->device_id; + + /* Only the first 32 feature bits are used. */ + dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus, +@@ -892,9 +898,10 @@ static unsigned virtio_ccw_get_features(DeviceState *d) + static void virtio_ccw_reset(DeviceState *d) + { + VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); ++ VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); + + virtio_ccw_stop_ioeventfd(dev); +- virtio_reset(dev->vdev); ++ virtio_reset(vdev); + css_reset_sch(dev->sch); + dev->indicators = 0; + dev->indicators2 = 0; +@@ -934,9 +941,10 @@ static int virtio_ccw_set_host_notifier(DeviceState *d, int n, bool assign) + static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n, + bool assign, bool with_irqfd) + { +- VirtQueue *vq = virtio_get_queue(dev->vdev, n); ++ VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); ++ VirtQueue *vq = virtio_get_queue(vdev, n); + EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); +- VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev); ++ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + + if (assign) { + int r = event_notifier_init(notifier, 0); +@@ -952,16 +960,16 @@ static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n, + * land in qemu (and only the irq fd) in this code. + */ + if (k->guest_notifier_mask) { +- k->guest_notifier_mask(dev->vdev, n, false); ++ k->guest_notifier_mask(vdev, n, false); + } + /* get lost events and re-inject */ + if (k->guest_notifier_pending && +- k->guest_notifier_pending(dev->vdev, n)) { ++ k->guest_notifier_pending(vdev, n)) { + event_notifier_set(notifier); + } + } else { + if (k->guest_notifier_mask) { +- k->guest_notifier_mask(dev->vdev, n, true); ++ k->guest_notifier_mask(vdev, n, true); + } + virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); + event_notifier_cleanup(notifier); +@@ -973,7 +981,7 @@ static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs, + bool assigned) + { + VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); +- VirtIODevice *vdev = dev->vdev; ++ VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); + int r, n; + + for (n = 0; n < nvqs; n++) { diff --git a/0007-virtio-bus-cleanup-plug-unplug-interface.patch b/0007-virtio-bus-cleanup-plug-unplug-interface.patch new file mode 100644 index 0000000..aa86829 --- /dev/null +++ b/0007-virtio-bus-cleanup-plug-unplug-interface.patch @@ -0,0 +1,148 @@ +From e26f88b6280b2386c36d3b3d5ec820deb1ac7749 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:53 +0200 +Subject: [PATCH] virtio-bus: cleanup plug/unplug interface + +Right now we have these pairs: + +- virtio_bus_plug_device/virtio_bus_destroy_device. The first + takes a VirtIODevice, the second takes a VirtioBusState + +- device_plugged/device_unplug callbacks in the VirtioBusClass + (here it's just the naming that is inconsistent) + +- virtio_bus_destroy_device is not called by anyone (and since + it calls qdev_free, it would be called by the proxies---but + then the callback is useless since the proxies can do whatever + they want before calling virtio_bus_destroy_device) + +And there is a k->init but no k->exit, hence virtio_device_exit is +overwritten by subclasses (except virtio-9p). This cleans it up by: + +- renaming the device_unplug callback to device_unplugged + +- renaming virtio_bus_plug_device to virtio_bus_device_plugged, + matching the callback name + +- renaming virtio_bus_destroy_device to virtio_bus_device_unplugged, + removing the qdev_free, making it take a VirtIODevice and calling it + from virtio_device_exit + +- adding a k->exit callback + +virtio_device_exit is still overwritten, the next patches will fix that. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-bus.c | 18 +++++++++--------- + hw/virtio/virtio.c | 7 ++++++- + include/hw/virtio/virtio-bus.h | 6 +++--- + include/hw/virtio/virtio.h | 1 + + 4 files changed, 19 insertions(+), 13 deletions(-) + +diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c +index 17dd06e..7aed6a4 100644 +--- a/hw/virtio/virtio-bus.c ++++ b/hw/virtio/virtio-bus.c +@@ -37,8 +37,8 @@ do { printf("virtio_bus: " fmt , ## __VA_ARGS__); } while (0) + #define DPRINTF(fmt, ...) do { } while (0) + #endif + +-/* Plug the VirtIODevice */ +-int virtio_bus_plug_device(VirtIODevice *vdev) ++/* A VirtIODevice is being plugged */ ++int virtio_bus_device_plugged(VirtIODevice *vdev) + { + DeviceState *qdev = DEVICE(vdev); + BusState *qbus = BUS(qdev_get_parent_bus(qdev)); +@@ -64,20 +64,20 @@ void virtio_bus_reset(VirtioBusState *bus) + } + } + +-/* Destroy the VirtIODevice */ +-void virtio_bus_destroy_device(VirtioBusState *bus) ++/* A VirtIODevice is being unplugged */ ++void virtio_bus_device_unplugged(VirtIODevice *vdev) + { +- BusState *qbus = BUS(bus); ++ DeviceState *qdev = DEVICE(vdev); ++ BusState *qbus = BUS(qdev_get_parent_bus(qdev)); ++ VirtioBusState *bus = VIRTIO_BUS(qbus); + VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); +- VirtIODevice *vdev = virtio_bus_get_device(bus); + + DPRINTF("%s: remove device.\n", qbus->name); + + if (vdev != NULL) { +- if (klass->device_unplug != NULL) { +- klass->device_unplug(qbus->parent); ++ if (klass->device_unplugged != NULL) { ++ klass->device_unplugged(qbus->parent); + } +- object_unparent(OBJECT(vdev)); + } + } + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 2f1e73b..965b2c0 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -1158,14 +1158,19 @@ static int virtio_device_init(DeviceState *qdev) + if (k->init(vdev) < 0) { + return -1; + } +- virtio_bus_plug_device(vdev); ++ virtio_bus_device_plugged(vdev); + return 0; + } + + static int virtio_device_exit(DeviceState *qdev) + { + VirtIODevice *vdev = VIRTIO_DEVICE(qdev); ++ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev); + ++ virtio_bus_device_unplugged(vdev); ++ if (k->exit) { ++ k->exit(vdev); ++ } + if (vdev->bus_name) { + g_free(vdev->bus_name); + vdev->bus_name = NULL; +diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h +index ba0f86a..0756545 100644 +--- a/include/hw/virtio/virtio-bus.h ++++ b/include/hw/virtio/virtio-bus.h +@@ -61,7 +61,7 @@ typedef struct VirtioBusClass { + * transport independent exit function. + * This is called by virtio-bus just before the device is unplugged. + */ +- void (*device_unplug)(DeviceState *d); ++ void (*device_unplugged)(DeviceState *d); + /* + * Does the transport have variable vring alignment? + * (ie can it ever call virtio_queue_set_align()?) +@@ -74,9 +74,9 @@ struct VirtioBusState { + BusState parent_obj; + }; + +-int virtio_bus_plug_device(VirtIODevice *vdev); ++int virtio_bus_device_plugged(VirtIODevice *vdev); + void virtio_bus_reset(VirtioBusState *bus); +-void virtio_bus_destroy_device(VirtioBusState *bus); ++void virtio_bus_device_unplugged(VirtIODevice *bus); + /* Get the device id of the plugged device. */ + uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus); + /* Get the config_len field of the plugged device. */ +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index a90522d..59756c2 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -127,6 +127,7 @@ typedef struct VirtioDeviceClass { + /* This is what a VirtioDevice must implement */ + DeviceClass parent; + int (*init)(VirtIODevice *vdev); ++ void (*exit)(VirtIODevice *vdev); + uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features); + uint32_t (*bad_features)(VirtIODevice *vdev); + void (*set_features)(VirtIODevice *vdev, uint32_t val); diff --git a/0007-virtio-console-Enable-port-throttling-when-chardev-i.patch b/0007-virtio-console-Enable-port-throttling-when-chardev-i.patch deleted file mode 100644 index 31d3565..0000000 --- a/0007-virtio-console-Enable-port-throttling-when-chardev-i.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 563ef1912e4b0c0b5728bc53d2b225d2ff3cd9ef Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Mon, 21 Mar 2011 22:06:41 +0100 -Subject: [PATCH] virtio-console: Enable port throttling when chardev is slow - to consume data - -When a chardev indicates it can't accept more data, we tell the -virtio-serial code to stop sending us any more data till we tell -otherwise. This helps in guests continuing to run normally while the vq -keeps getting full and eventually the guest stops queueing more data. -As soon as the chardev indicates it can accept more data, start pushing! - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - hw/virtio-console.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/hw/virtio-console.c b/hw/virtio-console.c -index dd6f614..0e12514 100644 ---- a/hw/virtio-console.c -+++ b/hw/virtio-console.c -@@ -20,6 +20,16 @@ typedef struct VirtConsole { - CharDriverState *chr; - } VirtConsole; - -+/* -+ * Callback function that's called from chardevs when backend becomes -+ * writable. -+ */ -+static void chr_write_unblocked(void *opaque) -+{ -+ VirtConsole *vcon = opaque; -+ -+ virtio_serial_throttle_port(&vcon->port, false); -+} - - /* Callback function that's called when the guest sends us data */ - static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) -@@ -110,6 +120,7 @@ static const QemuChrHandlers chr_handlers = { - .fd_can_read = chr_can_read, - .fd_read = chr_read, - .fd_event = chr_event, -+ .fd_write_unblocked = chr_write_unblocked, - }; - - static int virtconsole_initfn(VirtIOSerialPort *port) diff --git a/0008-spice-qemu-char.c-add-throttling.patch b/0008-spice-qemu-char.c-add-throttling.patch deleted file mode 100644 index 09ec001..0000000 --- a/0008-spice-qemu-char.c-add-throttling.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 7f533f631ffb62d2330003e687d47c83d3359026 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 22 Mar 2011 12:27:59 +0200 -Subject: [PATCH] spice-qemu-char.c: add throttling - -BZ: 672191 - -upstream: not submitted (explained below) - -Adds throttling support to spicevmc chardev. Uses a timer to avoid recursing: -1. spice-server: reds.c: read_from_vdi_port -2. qemu: spice-qemu-char.c: vmc_read -3. chr_write_unblocked - (calls virtio_serial_throttle_port(port, false)) -4. qemu: virtio ... -5. qemu: spice-qemu-char.c: spice_chr_write -6. qemu: spice-qemu-char.c: wakeup (calls into spice-server) -7. spice-server: ... -8. qemu: spice-qemu-char.c: vmc_read - -Instead, in vmc_read if we were throttled and we are just about to return -all the bytes we will set a timer to be triggered immediately to call -chr_write_unblocked. Then we return after 2 above, and 3 is called from the -timer callback. This also means we can later remove some ugly recursion protection -from spice-server. - -The other tricky point in this patch is not returning the leftover chunk twice. -When we throttle, by definition we have data that spice server didn't consume. -It is being kept by virtio-serial, and by us. The next vmc_read callback needs -to not return it, but just do unthrottling. Then virtio will give us the remaining -chunk as usual in spice_chr_write, and we will pass it to spice server in the -next vmc_read. - -This patch relies on Amit's series to expose throttling to chardev's, which -was not accepted upstream, and will not be accepted upstream until the mainloop -is reworked to use glib. - -Signed-off-by: Cole Robinson ---- - spice-qemu-char.c | 39 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 35 insertions(+), 4 deletions(-) - -diff --git a/spice-qemu-char.c b/spice-qemu-char.c -index a4d7de8..75bb125 100644 ---- a/spice-qemu-char.c -+++ b/spice-qemu-char.c -@@ -1,4 +1,6 @@ - #include "config-host.h" -+#include "qemu-common.h" -+#include "qemu/timer.h" - #include "trace.h" - #include "ui/qemu-spice.h" - #include "char/char.h" -@@ -25,6 +27,7 @@ typedef struct SpiceCharDriver { - uint8_t *datapos; - ssize_t bufsize, datalen; - uint32_t debug; -+ QEMUTimer *unblock_timer; - QLIST_ENTRY(SpiceCharDriver) next; - } SpiceCharDriver; - -@@ -54,6 +57,17 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) - return out; - } - -+static void spice_chr_unblock(void *opaque) -+{ -+ SpiceCharDriver *scd = opaque; -+ -+ if (scd->chr->chr_write_unblocked == NULL) { -+ dprintf(scd, 1, "%s: backend doesn't support unthrottling.\n", __func__); -+ return; -+ } -+ scd->chr->chr_write_unblocked(scd->chr->handler_opaque); -+} -+ - static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) - { - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); -@@ -65,9 +79,16 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) - scd->datapos += bytes; - scd->datalen -= bytes; - assert(scd->datalen >= 0); -- if (scd->datalen == 0) { -- scd->datapos = 0; -- } -+ } -+ if (scd->datalen == 0 && scd->chr->write_blocked) { -+ dprintf(scd, 1, "%s: unthrottling (%d)\n", __func__, bytes); -+ scd->chr->write_blocked = false; -+ /* -+ * set a timer instead of calling scd->chr->chr_write_unblocked directly, -+ * because that will call back into spice_chr_write (see -+ * virtio-console.c:chr_write_unblocked), which is unwanted. -+ */ -+ qemu_mod_timer(scd->unblock_timer, 0); - } - trace_spice_vmc_read(bytes, len); - return bytes; -@@ -163,6 +184,7 @@ static void vmc_unregister_interface(SpiceCharDriver *scd) - static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - { - SpiceCharDriver *s = chr->opaque; -+ int read_bytes; - - dprintf(s, 2, "%s: %d\n", __func__, len); - vmc_register_interface(s); -@@ -175,7 +197,15 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - s->datapos = s->buffer; - s->datalen = len; - spice_server_char_device_wakeup(&s->sin); -- return len; -+ read_bytes = len - s->datalen; -+ if (read_bytes != len) { -+ dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__, -+ read_bytes, len, s->bufsize); -+ s->chr->write_blocked = true; -+ /* We'll get passed in the unconsumed data with the next call */ -+ s->datalen = 0; -+ } -+ return read_bytes; - } - - static void spice_chr_close(struct CharDriverState *chr) -@@ -234,6 +264,7 @@ static CharDriverState *chr_open(QemuOpts *opts, const char *subtype) - chr->chr_close = spice_chr_close; - chr->chr_guest_open = spice_chr_guest_open; - chr->chr_guest_close = spice_chr_guest_close; -+ s->unblock_timer = qemu_new_timer_ms(vm_clock, spice_chr_unblock, s); - - QLIST_INSERT_HEAD(&spice_chars, s, next); - diff --git a/0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch b/0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch new file mode 100644 index 0000000..cbf3ad3 --- /dev/null +++ b/0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch @@ -0,0 +1,53 @@ +From e8821c68009a5b801ffef6d7d9ed5d770c0bfd9f Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:54 +0200 +Subject: [PATCH] virtio-blk: switch exit callback to VirtioDeviceClass + +This ensures hot-unplug is handled properly by the proxy. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/block/virtio-blk.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index 13f6d82..7f0440f 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -728,20 +728,18 @@ static int virtio_blk_device_init(VirtIODevice *vdev) + return 0; + } + +-static int virtio_blk_device_exit(DeviceState *dev) ++static void virtio_blk_device_exit(VirtIODevice *vdev) + { +- VirtIODevice *vdev = VIRTIO_DEVICE(dev); +- VirtIOBlock *s = VIRTIO_BLK(dev); ++ VirtIOBlock *s = VIRTIO_BLK(vdev); + #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + remove_migration_state_change_notifier(&s->migration_state_notifier); + virtio_blk_data_plane_destroy(s->dataplane); + s->dataplane = NULL; + #endif + qemu_del_vm_change_state_handler(s->change); +- unregister_savevm(dev, "virtio-blk", s); ++ unregister_savevm(DEVICE(vdev), "virtio-blk", s); + blockdev_mark_auto_del(s->bs); + virtio_cleanup(vdev); +- return 0; + } + + static Property virtio_blk_properties[] = { +@@ -753,10 +751,10 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); +- dc->exit = virtio_blk_device_exit; + dc->props = virtio_blk_properties; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + vdc->init = virtio_blk_device_init; ++ vdc->exit = virtio_blk_device_exit; + vdc->get_config = virtio_blk_update_config; + vdc->set_config = virtio_blk_set_config; + vdc->get_features = virtio_blk_get_features; diff --git a/0009-spice-qemu-char.c-remove-intermediate-buffer.patch b/0009-spice-qemu-char.c-remove-intermediate-buffer.patch deleted file mode 100644 index 12b81e3..0000000 --- a/0009-spice-qemu-char.c-remove-intermediate-buffer.patch +++ /dev/null @@ -1,70 +0,0 @@ -From d126441f71fde3b8a1d1cfea62d05382faea0985 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 22 Mar 2011 12:28:00 +0200 -Subject: [PATCH] spice-qemu-char.c: remove intermediate buffer - -BZ: 672191 -upstream: not submitted (explained below) - -virtio-serial's buffer is valid when it calls us, and we don't -access it otherwise: vmc_read is only called in response to wakeup, -or else we set datalen=0 and throttle. Then vmc_read is called back, -we return 0 (not accessing the buffer) and set the timer to unthrottle. - -Also make datalen int and not ssize_t (to fit spice_chr_write signature). - -This relied on the previous patch that introduces throttling, which -can't go upstream right now as explained in that patch. - -Signed-off-by: Cole Robinson ---- - spice-qemu-char.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - -diff --git a/spice-qemu-char.c b/spice-qemu-char.c -index 75bb125..5065240 100644 ---- a/spice-qemu-char.c -+++ b/spice-qemu-char.c -@@ -23,9 +23,8 @@ typedef struct SpiceCharDriver { - SpiceCharDeviceInstance sin; - char *subtype; - bool active; -- uint8_t *buffer; -- uint8_t *datapos; -- ssize_t bufsize, datalen; -+ const uint8_t *datapos; -+ int datalen; - uint32_t debug; - QEMUTimer *unblock_timer; - QLIST_ENTRY(SpiceCharDriver) next; -@@ -73,7 +72,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); - int bytes = MIN(len, scd->datalen); - -- dprintf(scd, 2, "%s: %p %d/%d/%zd\n", __func__, scd->datapos, len, bytes, scd->datalen); -+ dprintf(scd, 2, "%s: %p %d/%d/%d\n", __func__, scd->datapos, len, bytes, scd->datalen); - if (bytes > 0) { - memcpy(buf, scd->datapos, bytes); - scd->datapos += bytes; -@@ -189,18 +188,13 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) - dprintf(s, 2, "%s: %d\n", __func__, len); - vmc_register_interface(s); - assert(s->datalen == 0); -- if (s->bufsize < len) { -- s->bufsize = len; -- s->buffer = g_realloc(s->buffer, s->bufsize); -- } -- memcpy(s->buffer, buf, len); -- s->datapos = s->buffer; -+ s->datapos = buf; - s->datalen = len; - spice_server_char_device_wakeup(&s->sin); - read_bytes = len - s->datalen; - if (read_bytes != len) { -- dprintf(s, 1, "%s: throttling: %d < %d (%zd)\n", __func__, -- read_bytes, len, s->bufsize); -+ dprintf(s, 1, "%s: throttling: %d < %d\n", __func__, -+ read_bytes, len); - s->chr->write_blocked = true; - /* We'll get passed in the unconsumed data with the next call */ - s->datalen = 0; diff --git a/0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch b/0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch new file mode 100644 index 0000000..840e1e3 --- /dev/null +++ b/0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch @@ -0,0 +1,53 @@ +From b4ea3493c8c99bd854eec8640bd5c90c31e8ac14 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:55 +0200 +Subject: [PATCH] virtio-serial: switch exit callback to VirtioDeviceClass + +This ensures hot-unplug is handled properly by the proxy. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/char/virtio-serial-bus.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c +index 703f026..a7ede90 100644 +--- a/hw/char/virtio-serial-bus.c ++++ b/hw/char/virtio-serial-bus.c +@@ -987,12 +987,11 @@ static const TypeInfo virtio_serial_port_type_info = { + .class_init = virtio_serial_port_class_init, + }; + +-static int virtio_serial_device_exit(DeviceState *dev) ++static void virtio_serial_device_exit(VirtIODevice *vdev) + { +- VirtIOSerial *vser = VIRTIO_SERIAL(dev); +- VirtIODevice *vdev = VIRTIO_DEVICE(dev); ++ VirtIOSerial *vser = VIRTIO_SERIAL(vdev); + +- unregister_savevm(dev, "virtio-console", vser); ++ unregister_savevm(DEVICE(vdev), "virtio-console", vser); + + g_free(vser->ivqs); + g_free(vser->ovqs); +@@ -1004,7 +1003,6 @@ static int virtio_serial_device_exit(DeviceState *dev) + g_free(vser->post_load); + } + virtio_cleanup(vdev); +- return 0; + } + + static Property virtio_serial_properties[] = { +@@ -1016,10 +1014,10 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); +- dc->exit = virtio_serial_device_exit; + dc->props = virtio_serial_properties; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); + vdc->init = virtio_serial_device_init; ++ vdc->exit = virtio_serial_device_exit; + vdc->get_features = get_features; + vdc->get_config = get_config; + vdc->set_config = set_config; diff --git a/0010-usb-redir-Add-flow-control-support.patch b/0010-usb-redir-Add-flow-control-support.patch deleted file mode 100644 index a94e7d5..0000000 --- a/0010-usb-redir-Add-flow-control-support.patch +++ /dev/null @@ -1,62 +0,0 @@ -From a0d12b6040efbe6aa8e6e74cef91cf613ff2bf55 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 19 Jul 2011 10:56:19 +0200 -Subject: [PATCH] usb-redir: Add flow control support - -Signed-off-by: Hans de Goede ---- - hw/usb/redirect.c | 22 ++++++++++++++++++++-- - 1 file changed, 20 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 2ee9ad1..bf6aaf0 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -257,8 +257,9 @@ static int usbredir_read(void *priv, uint8_t *data, int count) - static int usbredir_write(void *priv, uint8_t *data, int count) - { - USBRedirDevice *dev = priv; -+ int r; - -- if (!dev->cs->opened) { -+ if (!dev->cs->opened || dev->cs->write_blocked) { - return 0; - } - -@@ -267,7 +268,16 @@ static int usbredir_write(void *priv, uint8_t *data, int count) - return 0; - } - -- return qemu_chr_fe_write(dev->cs, data, count); -+ r = qemu_chr_fe_write(dev->cs, data, count); -+ -+ if (r < 0) { -+ if (dev->cs->write_blocked) { -+ return 0; -+ } -+ return -1; -+ } -+ -+ return r; - } - - /* -@@ -1227,10 +1237,18 @@ static void usbredir_chardev_event(void *opaque, int event) - } - } - -+static void usbredir_chardev_write_unblocked(void *opaque) -+{ -+ USBRedirDevice *dev = opaque; -+ -+ usbredirparser_do_write(dev->parser); -+} -+ - static const QemuChrHandlers usbredir_chr_handlers = { - .fd_can_read = usbredir_chardev_can_read, - .fd_read = usbredir_chardev_read, - .fd_event = usbredir_chardev_event, -+ .fd_write_unblocked = usbredir_chardev_write_unblocked, - }; - - /* diff --git a/0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch b/0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch new file mode 100644 index 0000000..0406b04 --- /dev/null +++ b/0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch @@ -0,0 +1,58 @@ +From d399f7bf1a035d6158d20d3f11a44f03e15132d0 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:56 +0200 +Subject: [PATCH] virtio-net: switch exit callback to VirtioDeviceClass + +This ensures hot-unplug is handled properly by the proxy. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/net/virtio-net.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index b75c753..93a81eb 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1570,16 +1570,15 @@ static int virtio_net_device_init(VirtIODevice *vdev) + return 0; + } + +-static int virtio_net_device_exit(DeviceState *qdev) ++static void virtio_net_device_exit(VirtIODevice *vdev) + { +- VirtIONet *n = VIRTIO_NET(qdev); +- VirtIODevice *vdev = VIRTIO_DEVICE(qdev); ++ VirtIONet *n = VIRTIO_NET(vdev); + int i; + + /* This will stop vhost backend if appropriate. */ + virtio_net_set_status(vdev, 0); + +- unregister_savevm(qdev, "virtio-net", n); ++ unregister_savevm(DEVICE(vdev), "virtio-net", n); + + if (n->netclient_name) { + g_free(n->netclient_name); +@@ -1610,8 +1609,6 @@ static int virtio_net_device_exit(DeviceState *qdev) + g_free(n->vqs); + qemu_del_nic(n->nic); + virtio_cleanup(vdev); +- +- return 0; + } + + static void virtio_net_instance_init(Object *obj) +@@ -1638,10 +1635,10 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); +- dc->exit = virtio_net_device_exit; + dc->props = virtio_net_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); + vdc->init = virtio_net_device_init; ++ vdc->exit = virtio_net_device_exit; + vdc->get_config = virtio_net_get_config; + vdc->set_config = virtio_net_set_config; + vdc->get_features = virtio_net_get_features; diff --git a/0011-char-Disable-write-callback-if-throttled-chardev-is-.patch b/0011-char-Disable-write-callback-if-throttled-chardev-is-.patch deleted file mode 100644 index 6e501c9..0000000 --- a/0011-char-Disable-write-callback-if-throttled-chardev-is-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8dec49852492007b4e5afc599376a4d88623cba8 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Fri, 2 Dec 2011 15:42:55 +0530 -Subject: [PATCH] char: Disable write callback if throttled chardev is detached - -If a throttled chardev is detached from the frontend device, all future -callbacks should be suppressed. Not doing this results in a segfault. - -Bugzilla: 745758 -Upstream: Not applicable, since throttling is a RHEL6-only feature. - -Signed-off-by: Amit Shah -Signed-off-by: Cole Robinson ---- - qemu-char.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/qemu-char.c b/qemu-char.c -index 53d2c13..fde72ff 100644 ---- a/qemu-char.c -+++ b/qemu-char.c -@@ -223,6 +223,11 @@ void qemu_chr_add_handlers(CharDriverState *s, - ++s->avail_connections; - } - if (!handlers) { -+ if (s->write_blocked) { -+ /* Ensure we disable the callback if we were throttled */ -+ s->chr_disable_write_fd_handler(s); -+ /* s->write_blocked is cleared below */ -+ } - handlers = &null_handlers; - } - s->chr_can_read = handlers->fd_can_read; diff --git a/0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch b/0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch new file mode 100644 index 0000000..d34ab57 --- /dev/null +++ b/0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch @@ -0,0 +1,112 @@ +From 18a73436b50ec6c28afde849c6de23ad7ebed459 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:57 +0200 +Subject: [PATCH] virtio-scsi: switch exit callback to VirtioDeviceClass + +This ensures hot-unplug is handled properly by the proxy. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/scsi/vhost-scsi.c | 11 +++++------ + hw/scsi/virtio-scsi.c | 15 +++++++-------- + include/hw/virtio/virtio-scsi.h | 2 +- + 3 files changed, 13 insertions(+), 15 deletions(-) + +diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c +index 9e770fb..5e3cc61 100644 +--- a/hw/scsi/vhost-scsi.c ++++ b/hw/scsi/vhost-scsi.c +@@ -240,11 +240,10 @@ static int vhost_scsi_init(VirtIODevice *vdev) + return 0; + } + +-static int vhost_scsi_exit(DeviceState *qdev) ++static void vhost_scsi_exit(VirtIODevice *vdev) + { +- VirtIODevice *vdev = VIRTIO_DEVICE(qdev); +- VHostSCSI *s = VHOST_SCSI(qdev); +- VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev); ++ VHostSCSI *s = VHOST_SCSI(vdev); ++ VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); + + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); +@@ -253,7 +252,7 @@ static int vhost_scsi_exit(DeviceState *qdev) + vhost_scsi_set_status(vdev, 0); + + g_free(s->dev.vqs); +- return virtio_scsi_common_exit(vs); ++ virtio_scsi_common_exit(vs); + } + + static Property vhost_scsi_properties[] = { +@@ -265,10 +264,10 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); +- dc->exit = vhost_scsi_exit; + dc->props = vhost_scsi_properties; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + vdc->init = vhost_scsi_init; ++ vdc->exit = vhost_scsi_exit; + vdc->get_features = vhost_scsi_get_features; + vdc->set_config = vhost_scsi_set_config; + vdc->set_status = vhost_scsi_set_status; +diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c +index 26d95a1..83344ea 100644 +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -644,22 +644,21 @@ static int virtio_scsi_device_init(VirtIODevice *vdev) + return 0; + } + +-int virtio_scsi_common_exit(VirtIOSCSICommon *vs) ++void virtio_scsi_common_exit(VirtIOSCSICommon *vs) + { + VirtIODevice *vdev = VIRTIO_DEVICE(vs); + + g_free(vs->cmd_vqs); + virtio_cleanup(vdev); +- return 0; + } + +-static int virtio_scsi_device_exit(DeviceState *qdev) ++static void virtio_scsi_device_exit(VirtIODevice *vdev) + { +- VirtIOSCSI *s = VIRTIO_SCSI(qdev); +- VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev); ++ VirtIOSCSI *s = VIRTIO_SCSI(vdev); ++ VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); + +- unregister_savevm(qdev, "virtio-scsi", s); +- return virtio_scsi_common_exit(vs); ++ unregister_savevm(DEVICE(vdev), "virtio-scsi", s); ++ virtio_scsi_common_exit(vs); + } + + static Property virtio_scsi_properties[] = { +@@ -680,10 +679,10 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); +- dc->exit = virtio_scsi_device_exit; + dc->props = virtio_scsi_properties; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + vdc->init = virtio_scsi_device_init; ++ vdc->exit = virtio_scsi_device_exit; + vdc->set_config = virtio_scsi_set_config; + vdc->get_features = virtio_scsi_get_features; + vdc->reset = virtio_scsi_reset; +diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h +index 9a98540..206c61d 100644 +--- a/include/hw/virtio/virtio-scsi.h ++++ b/include/hw/virtio/virtio-scsi.h +@@ -187,6 +187,6 @@ typedef struct { + VIRTIO_SCSI_F_CHANGE, true) + + int virtio_scsi_common_init(VirtIOSCSICommon *vs); +-int virtio_scsi_common_exit(VirtIOSCSICommon *vs); ++void virtio_scsi_common_exit(VirtIOSCSICommon *vs); + + #endif /* _QEMU_VIRTIO_SCSI_H */ diff --git a/0012-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch b/0012-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch deleted file mode 100644 index 58bbc97..0000000 --- a/0012-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 1a888642291d5bc49c657c313e4bc01b59f47d2a Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Fri, 16 Nov 2012 16:24:47 +0200 -Subject: [PATCH] hw/virtio-serial-bus: replay guest open on destination - -This is rewrite of a patch carried in Fedora previously based -on new code upstream, here is the original message, it still applies: -(the original fedora patch was commit id -a9bc20afc1f0604ee81c23b7c67d627e51d2e8d4, this is useful for grepping in -logs, it isn't in upstream) - -When migrating a host with with a spice agent running the mouse becomes -non operational after the migration. This is rhbz #725965. - -The problem is that after migration spice doesn't know the guest agent -is open. Spice is just a char dev here. And a chardev cannot query it's -device, the device has to let the chardev know when it is open. Right -now after migration the chardev which is recreated is in it's default -state, which assumes the guest is disconnected. - -Char devices carry no information across migration, but the -virtio-serial does already carry the guest_connected state. This patch -passes that bit to the chardev. ---- - hw/virtio-serial-bus.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index aa7d0d7..5078129 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -642,6 +642,7 @@ static void virtio_serial_post_load_timer_cb(void *opaque) - VirtIOSerial *s = opaque; - VirtIOSerialPort *port; - uint8_t host_connected; -+ VirtIOSerialPortClass *vsc; - - if (!s->post_load) { - return; -@@ -657,6 +658,11 @@ static void virtio_serial_post_load_timer_cb(void *opaque) - send_control_event(s, port->id, VIRTIO_CONSOLE_PORT_OPEN, - port->host_connected); - } -+ vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); -+ if (port->guest_connected && vsc->guest_open) { -+ /* replay guest open */ -+ vsc->guest_open(port); -+ } - } - g_free(s->post_load->connected); - qemu_free_timer(s->post_load->timer); diff --git a/0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch b/0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch new file mode 100644 index 0000000..004dc8c --- /dev/null +++ b/0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch @@ -0,0 +1,49 @@ +From 7f334f1eb88807e2fc7ae42cc729f8dd371833e4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:58 +0200 +Subject: [PATCH] virtio-balloon: switch exit callback to VirtioDeviceClass + +This ensures hot-unplug is handled properly by the proxy. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-balloon.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c +index 9504877..d7a392d 100644 +--- a/hw/virtio/virtio-balloon.c ++++ b/hw/virtio/virtio-balloon.c +@@ -370,16 +370,14 @@ static int virtio_balloon_device_init(VirtIODevice *vdev) + return 0; + } + +-static int virtio_balloon_device_exit(DeviceState *qdev) ++static void virtio_balloon_device_exit(VirtIODevice *vdev) + { +- VirtIOBalloon *s = VIRTIO_BALLOON(qdev); +- VirtIODevice *vdev = VIRTIO_DEVICE(qdev); ++ VirtIOBalloon *s = VIRTIO_BALLOON(vdev); + + balloon_stats_destroy_timer(s); + qemu_remove_balloon_handler(s); +- unregister_savevm(qdev, "virtio-balloon", s); ++ unregister_savevm(DEVICE(vdev), "virtio-balloon", s); + virtio_cleanup(vdev); +- return 0; + } + + static Property virtio_balloon_properties[] = { +@@ -390,10 +388,10 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); +- dc->exit = virtio_balloon_device_exit; + dc->props = virtio_balloon_properties; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + vdc->init = virtio_balloon_device_init; ++ vdc->exit = virtio_balloon_device_exit; + vdc->get_config = virtio_balloon_get_config; + vdc->set_config = virtio_balloon_set_config; + vdc->get_features = virtio_balloon_get_features; diff --git a/0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch b/0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch new file mode 100644 index 0000000..5eabe78 --- /dev/null +++ b/0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch @@ -0,0 +1,49 @@ +From 8b9a562e23dbfdfb23a5eeb1b619619290216ad8 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:57:59 +0200 +Subject: [PATCH] virtio-rng: switch exit callback to VirtioDeviceClass + +This ensures hot-unplug is handled properly by the proxy. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-rng.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c +index b22ccf1..42ca568 100644 +--- a/hw/virtio/virtio-rng.c ++++ b/hw/virtio/virtio-rng.c +@@ -190,16 +190,14 @@ static int virtio_rng_device_init(VirtIODevice *vdev) + return 0; + } + +-static int virtio_rng_device_exit(DeviceState *qdev) ++static void virtio_rng_device_exit(VirtIODevice *vdev) + { +- VirtIORNG *vrng = VIRTIO_RNG(qdev); +- VirtIODevice *vdev = VIRTIO_DEVICE(qdev); ++ VirtIORNG *vrng = VIRTIO_RNG(vdev); + + timer_del(vrng->rate_limit_timer); + timer_free(vrng->rate_limit_timer); +- unregister_savevm(qdev, "virtio-rng", vrng); ++ unregister_savevm(DEVICE(vdev), "virtio-rng", vrng); + virtio_cleanup(vdev); +- return 0; + } + + static Property virtio_rng_properties[] = { +@@ -211,10 +209,10 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); +- dc->exit = virtio_rng_device_exit; + dc->props = virtio_rng_properties; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + vdc->init = virtio_rng_device_init; ++ vdc->exit = virtio_rng_device_exit; + vdc->get_features = get_features; + } + diff --git a/0014-virtio-pci-add-device_unplugged-callback.patch b/0014-virtio-pci-add-device_unplugged-callback.patch new file mode 100644 index 0000000..5fdc5d9 --- /dev/null +++ b/0014-virtio-pci-add-device_unplugged-callback.patch @@ -0,0 +1,59 @@ +From 96412e68c312ae4d91d6febc2284951f8b295ef7 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 16:58:00 +0200 +Subject: [PATCH] virtio-pci: add device_unplugged callback + +This fixes a crash in hot-unplug of virtio-pci devices behind a PCIe +switch. The crash happens because the ioeventfd is still set whent the +child is destroyed (destruction happens in postorder). Then the proxy +tries to unset to ioeventfd, but the virtqueue structure that holds the +EventNotifier has been trashed in the meanwhile. kvm_set_ioeventfd_pio +does not expect failure and aborts. + +The fix is simply to move parts of uninitialization to a new +device_unplugged callback, which is called before the child is destroyed. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-pci.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index be18e92..1a363ca 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -1001,6 +1001,15 @@ static void virtio_pci_device_plugged(DeviceState *d) + proxy->host_features); + } + ++static void virtio_pci_device_unplugged(DeviceState *d) ++{ ++ PCIDevice *pci_dev = PCI_DEVICE(d); ++ VirtIOPCIProxy *proxy = VIRTIO_PCI(d); ++ ++ virtio_pci_stop_ioeventfd(proxy); ++ msix_uninit_exclusive_bar(pci_dev); ++} ++ + static int virtio_pci_init(PCIDevice *pci_dev) + { + VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev); +@@ -1015,9 +1024,7 @@ static int virtio_pci_init(PCIDevice *pci_dev) + static void virtio_pci_exit(PCIDevice *pci_dev) + { + VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev); +- virtio_pci_stop_ioeventfd(proxy); + memory_region_destroy(&proxy->bar); +- msix_uninit_exclusive_bar(pci_dev); + } + + static void virtio_pci_reset(DeviceState *qdev) +@@ -1552,6 +1559,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data) + k->set_guest_notifiers = virtio_pci_set_guest_notifiers; + k->vmstate_change = virtio_pci_vmstate_change; + k->device_plugged = virtio_pci_device_plugged; ++ k->device_unplugged = virtio_pci_device_unplugged; + } + + static const TypeInfo virtio_pci_bus_info = { diff --git a/0101-block-Close-backing-file-early-in-bdrv_img_create.patch b/0101-block-Close-backing-file-early-in-bdrv_img_create.patch new file mode 100644 index 0000000..86d4ad1 --- /dev/null +++ b/0101-block-Close-backing-file-early-in-bdrv_img_create.patch @@ -0,0 +1,72 @@ +From 62a30a970548466900ac45962a0fe8c051514329 Mon Sep 17 00:00:00 2001 +From: Max Reitz +Date: Tue, 3 Dec 2013 14:57:52 +0100 +Subject: [PATCH] block: Close backing file early in bdrv_img_create + +Leaving the backing file open although it is not needed anymore can +cause problems if it is opened through a block driver which allows +exclusive access only and if the create function of the block driver +used for the top image (the one being created) tries to close and reopen +the image file (which will include opening the backing file a second +time). + +In particular, this will happen with a backing file opened through +qemu-nbd and using qcow2 as the top image file format (which reopens the +image to flush it to disk). + +In addition, the BlockDriverState in bdrv_img_create() is used for the +backing file only; it should therefore be made local to the respective +block. + +Signed-off-by: Max Reitz +--- + block.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/block.c b/block.c +index 382ea71..0468765 100644 +--- a/block.c ++++ b/block.c +@@ -4504,7 +4504,6 @@ void bdrv_img_create(const char *filename, const char *fmt, + { + QEMUOptionParameter *param = NULL, *create_options = NULL; + QEMUOptionParameter *backing_fmt, *backing_file, *size; +- BlockDriverState *bs = NULL; + BlockDriver *drv, *proto_drv; + BlockDriver *backing_drv = NULL; + Error *local_err = NULL; +@@ -4583,6 +4582,7 @@ void bdrv_img_create(const char *filename, const char *fmt, + size = get_option_parameter(param, BLOCK_OPT_SIZE); + if (size && size->value.n == -1) { + if (backing_file && backing_file->value.s) { ++ BlockDriverState *bs; + uint64_t size; + char buf[32]; + int back_flags; +@@ -4601,6 +4601,7 @@ void bdrv_img_create(const char *filename, const char *fmt, + error_get_pretty(local_err)); + error_free(local_err); + local_err = NULL; ++ bdrv_unref(bs); + goto out; + } + bdrv_get_geometry(bs, &size); +@@ -4608,6 +4609,8 @@ void bdrv_img_create(const char *filename, const char *fmt, + + snprintf(buf, sizeof(buf), "%" PRId64, size); + set_option_parameter(param, BLOCK_OPT_SIZE, buf); ++ ++ bdrv_unref(bs); + } else { + error_setg(errp, "Image creation needs a size parameter"); + goto out; +@@ -4638,9 +4641,6 @@ out: + free_option_parameters(create_options); + free_option_parameters(param); + +- if (bs) { +- bdrv_unref(bs); +- } + if (error_is_set(&local_err)) { + error_propagate(errp, local_err); + } diff --git a/0101-vnc-tls-Fix-compilation-with-newer-versions-of-GNU-T.patch b/0101-vnc-tls-Fix-compilation-with-newer-versions-of-GNU-T.patch deleted file mode 100644 index 8c5fa1a..0000000 --- a/0101-vnc-tls-Fix-compilation-with-newer-versions-of-GNU-T.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0aa1a9b167ca8a32d7c7112df375ddfa608f1f72 Mon Sep 17 00:00:00 2001 -From: Andre Przywara -Date: Thu, 18 Oct 2012 11:16:58 +0200 -Subject: [PATCH] vnc-tls: Fix compilation with newer versions of GNU-TLS - -In my installation of GNU-TLS (v3.0.23) the type -gnutls_anon_server_credentials is marked deprecated, so -Werror -breaks compilation. -Simply replacing it with the newer ..._t version fixed the compilation -on my machine (Slackware 14.0). I cannot tell how far back this "new" -type goes, at least the header file in RHEL 5.0 (v1.4.1) seems to have -it already. If someone finds a broken distribution, tell me and I -insert some compat code. - -Signed-off-by: Andre Przywara -Message-id: 1350551818-14717-1-git-send-email-andre.przywara@amd.com -Signed-off-by: Anthony Liguori -(cherry picked from commit 7d2a929feba319c18603e324b1750830d6c8b7a1) ---- - ui/vnc-tls.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c -index 5629263..8d4cc8e 100644 ---- a/ui/vnc-tls.c -+++ b/ui/vnc-tls.c -@@ -99,9 +99,9 @@ static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport, - } - - --static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void) -+static gnutls_anon_server_credentials_t vnc_tls_initialize_anon_cred(void) - { -- gnutls_anon_server_credentials anon_cred; -+ gnutls_anon_server_credentials_t anon_cred; - int ret; - - if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) { -@@ -382,7 +382,7 @@ int vnc_tls_client_setup(struct VncState *vs, - } - - } else { -- gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred(); -+ gnutls_anon_server_credentials_t anon_cred = vnc_tls_initialize_anon_cred(); - if (!anon_cred) { - gnutls_deinit(vs->tls.session); - vs->tls.session = NULL; diff --git a/0102-migration-change-initial-value-of-expected_downtime.patch b/0102-migration-change-initial-value-of-expected_downtime.patch deleted file mode 100644 index 770e9c2..0000000 --- a/0102-migration-change-initial-value-of-expected_downtime.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 60388b2884f904b408ec8650ab2af0a03ea7073e Mon Sep 17 00:00:00 2001 -From: Juan Quintela -Date: Fri, 1 Feb 2013 11:12:26 +0100 -Subject: [PATCH] migration: change initial value of expected_downtime - -0 is a very bad initial value, what we are trying to get is -max_downtime, so that is a much better estimation. - -Signed-off-by: Juan Quintela - -Reviewed-by: Orit Wasserman -(cherry picked from commit cc283e3bf04d2f64eb6ec2ee5bcd36edd779fe89) ---- - migration.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/migration.c b/migration.c -index 98c7696..3584a24 100644 ---- a/migration.c -+++ b/migration.c -@@ -774,6 +774,8 @@ void migrate_fd_connect(MigrationState *s) - s->buffer = NULL; - s->buffer_size = 0; - s->buffer_capacity = 0; -+ /* This is a best 1st approximation. ns to ms */ -+ s->expected_downtime = max_downtime/1000000; - - s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; - s->complete = false; diff --git a/0322-seccomp-add-kill-to-the-syscall-whitelist.patch b/0102-seccomp-add-kill-to-the-syscall-whitelist.patch similarity index 88% rename from 0322-seccomp-add-kill-to-the-syscall-whitelist.patch rename to 0102-seccomp-add-kill-to-the-syscall-whitelist.patch index 2984d8e..b101332 100644 --- a/0322-seccomp-add-kill-to-the-syscall-whitelist.patch +++ b/0102-seccomp-add-kill-to-the-syscall-whitelist.patch @@ -1,4 +1,4 @@ -From b16e5be879fd7386f0ad672ea02e3acee36d1e8e Mon Sep 17 00:00:00 2001 +From cebb1cd8d123360634243ac527c136721fb7fba7 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Thu, 21 Nov 2013 10:40:15 -0500 Subject: [PATCH] seccomp: add kill() to the syscall whitelist @@ -29,10 +29,10 @@ Acked-by: Eduardo Otubo 1 file changed, 1 insertion(+) diff --git a/qemu-seccomp.c b/qemu-seccomp.c -index 4a57b4b..c85f608 100644 +index 69cee44..cf07869 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c -@@ -121,6 +121,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { +@@ -114,6 +114,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { { SCMP_SYS(write), 244 }, { SCMP_SYS(fcntl), 243 }, { SCMP_SYS(tgkill), 242 }, diff --git a/0103-migration-calculate-end-time-after-we-have-sent-the-.patch b/0103-migration-calculate-end-time-after-we-have-sent-the-.patch deleted file mode 100644 index 1fe37d6..0000000 --- a/0103-migration-calculate-end-time-after-we-have-sent-the-.patch +++ /dev/null @@ -1,34 +0,0 @@ -From f34eeb6b65d36c31a0e412eefae1f735e48a3a69 Mon Sep 17 00:00:00 2001 -From: Juan Quintela -Date: Fri, 1 Feb 2013 12:39:08 +0100 -Subject: [PATCH] migration: calculate end time after we have sent the data - -Signed-off-by: Juan Quintela - -Reviewed-by: Orit Wasserman -(cherry picked from commit a3e879cd51c4f614f702117c4b1449f0218c00f3) ---- - migration.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/migration.c b/migration.c -index 3584a24..0026f08 100644 ---- a/migration.c -+++ b/migration.c -@@ -673,7 +673,7 @@ static void *buffered_file_thread(void *opaque) - qemu_mutex_unlock_iothread(); - - while (true) { -- int64_t current_time = qemu_get_clock_ms(rt_clock); -+ int64_t current_time; - uint64_t pending_size; - - qemu_mutex_lock_iothread(); -@@ -727,6 +727,7 @@ static void *buffered_file_thread(void *opaque) - } - } - qemu_mutex_unlock_iothread(); -+ current_time = qemu_get_clock_ms(rt_clock); - if (current_time >= initial_time + BUFFER_DELAY) { - uint64_t transferred_bytes = s->bytes_xfer; - uint64_t time_spent = current_time - initial_time; diff --git a/0323-spice-flip-streaming-video-mode-to-off-by-default.patch b/0103-spice-flip-streaming-video-mode-to-off-by-default.patch similarity index 88% rename from 0323-spice-flip-streaming-video-mode-to-off-by-default.patch rename to 0103-spice-flip-streaming-video-mode-to-off-by-default.patch index c2c62e6..afa6ac5 100644 --- a/0323-spice-flip-streaming-video-mode-to-off-by-default.patch +++ b/0103-spice-flip-streaming-video-mode-to-off-by-default.patch @@ -1,4 +1,4 @@ -From 3bbf8ef814e238de967eb1ef90f63c23e1942ecd Mon Sep 17 00:00:00 2001 +From 200413b505dfc4ae8611d523e87f1dee18a6bf0f Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 2 Dec 2013 11:17:04 +0100 Subject: [PATCH] spice: flip streaming video mode to off by default @@ -19,10 +19,10 @@ Reviewed-by: Alon Levy 1 file changed, 2 insertions(+) diff --git a/ui/spice-core.c b/ui/spice-core.c -index bcc4199..76e5dcd 100644 +index e4d533d..9fb9544 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c -@@ -764,6 +764,8 @@ void qemu_spice_init(void) +@@ -776,6 +776,8 @@ void qemu_spice_init(void) if (str) { int streaming_video = parse_stream_video(str); spice_server_set_streaming_video(spice_server, streaming_video); diff --git a/0104-migration-don-t-account-sleep-time-for-calculating-b.patch b/0104-migration-don-t-account-sleep-time-for-calculating-b.patch deleted file mode 100644 index d81b666..0000000 --- a/0104-migration-don-t-account-sleep-time-for-calculating-b.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 84b78ab739083a154713d89384b85550b39f2057 Mon Sep 17 00:00:00 2001 -From: Juan Quintela -Date: Fri, 1 Feb 2013 12:41:38 +0100 -Subject: [PATCH] migration: don't account sleep time for calculating bandwidth - -While we are sleeping we are not sending, so we should not use that -time to estimate our bandwidth. - -Signed-off-by: Juan Quintela - -Reviewed-by: Orit Wasserman -(cherry picked from commit 7161082c8d8cf167c508976887a0a63f4db92b51) ---- - migration.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/migration.c b/migration.c -index 0026f08..ebfbbde 100644 ---- a/migration.c -+++ b/migration.c -@@ -658,6 +658,7 @@ static void *buffered_file_thread(void *opaque) - { - MigrationState *s = opaque; - int64_t initial_time = qemu_get_clock_ms(rt_clock); -+ int64_t sleep_time = 0; - int64_t max_size = 0; - bool last_round = false; - int ret; -@@ -730,7 +731,7 @@ static void *buffered_file_thread(void *opaque) - current_time = qemu_get_clock_ms(rt_clock); - if (current_time >= initial_time + BUFFER_DELAY) { - uint64_t transferred_bytes = s->bytes_xfer; -- uint64_t time_spent = current_time - initial_time; -+ uint64_t time_spent = current_time - initial_time - sleep_time; - double bandwidth = transferred_bytes / time_spent; - max_size = bandwidth * migrate_max_downtime() / 1000000; - -@@ -739,11 +740,13 @@ static void *buffered_file_thread(void *opaque) - transferred_bytes, time_spent, bandwidth, max_size); - - s->bytes_xfer = 0; -+ sleep_time = 0; - initial_time = current_time; - } - if (!last_round && (s->bytes_xfer >= s->xfer_limit)) { - /* usleep expects microseconds */ - g_usleep((initial_time + BUFFER_DELAY - current_time)*1000); -+ sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } - ret = buffered_flush(s); - if (ret < 0) { diff --git a/0104-scsi-bus-fix-transfer-length-and-direction-for-VERIF.patch b/0104-scsi-bus-fix-transfer-length-and-direction-for-VERIF.patch new file mode 100644 index 0000000..a204453 --- /dev/null +++ b/0104-scsi-bus-fix-transfer-length-and-direction-for-VERIF.patch @@ -0,0 +1,59 @@ +From 3b1f248f3f8ff06ed4a4269871138db66e336ec5 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 28 Nov 2013 11:01:13 +0100 +Subject: [PATCH] scsi-bus: fix transfer length and direction for VERIFY + command +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The amount of bytes to transfer depends on the BYTCHK field. +If any data is transferred, it is sent to the device. + +Cc: qemu-stable@nongnu.org +Tested-by: Hervé Poussineau +Signed-off-by: Paolo Bonzini +(cherry picked from commit d12ad44cc4cc9142179e64295608611f118b8ad8) +--- + hw/scsi/scsi-bus.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c +index ea916d1..2d6ce4d 100644 +--- a/hw/scsi/scsi-bus.c ++++ b/hw/scsi/scsi-bus.c +@@ -886,7 +886,6 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) + case RELEASE: + case ERASE: + case ALLOW_MEDIUM_REMOVAL: +- case VERIFY_10: + case SEEK_10: + case SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE_16: +@@ -903,6 +902,16 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) + case ALLOW_OVERWRITE: + cmd->xfer = 0; + break; ++ case VERIFY_10: ++ case VERIFY_12: ++ case VERIFY_16: ++ if ((buf[1] & 2) == 0) { ++ cmd->xfer = 0; ++ } else if ((buf[1] & 4) == 1) { ++ cmd->xfer = 1; ++ } ++ cmd->xfer *= dev->blocksize; ++ break; + case MODE_SENSE: + break; + case WRITE_SAME_10: +@@ -1100,6 +1109,9 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd) + case WRITE_VERIFY_12: + case WRITE_16: + case WRITE_VERIFY_16: ++ case VERIFY_10: ++ case VERIFY_12: ++ case VERIFY_16: + case COPY: + case COPY_VERIFY: + case COMPARE: diff --git a/0105-migration-calculate-expected_downtime.patch b/0105-migration-calculate-expected_downtime.patch deleted file mode 100644 index 4475ea9..0000000 --- a/0105-migration-calculate-expected_downtime.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0d9d4a5c179f09bd801ba3470b97e1fd3f184ce2 Mon Sep 17 00:00:00 2001 -From: Juan Quintela -Date: Fri, 1 Feb 2013 13:22:37 +0100 -Subject: [PATCH] migration: calculate expected_downtime - -We removed the calculation in commit e4ed1541ac9413eac494a03532e34beaf8a7d1c5 - -Now we add it back. We need to create dirty_bytes_rate because we -can't include cpu-all.h from migration.c, and there is no other way to -include TARGET_PAGE_SIZE. - -Signed-off-by: Juan Quintela - -Reviewed-by: Orit Wasserman -(cherry picked from commit 90f8ae724a575861f093fbdbfd49a925bcfec327) ---- - arch_init.c | 1 + - include/migration/migration.h | 1 + - migration.c | 5 +++++ - 3 files changed, 7 insertions(+) - -diff --git a/arch_init.c b/arch_init.c -index 8da868b..8daeafa 100644 ---- a/arch_init.c -+++ b/arch_init.c -@@ -414,6 +414,7 @@ static void migration_bitmap_sync(void) - if (end_time > start_time + 1000) { - s->dirty_pages_rate = num_dirty_pages_period * 1000 - / (end_time - start_time); -+ s->dirty_bytes_rate = s->dirty_pages_rate * TARGET_PAGE_SIZE; - start_time = end_time; - num_dirty_pages_period = 0; - } -diff --git a/include/migration/migration.h b/include/migration/migration.h -index a8c9639..d121409 100644 ---- a/include/migration/migration.h -+++ b/include/migration/migration.h -@@ -51,6 +51,7 @@ struct MigrationState - int64_t downtime; - int64_t expected_downtime; - int64_t dirty_pages_rate; -+ int64_t dirty_bytes_rate; - bool enabled_capabilities[MIGRATION_CAPABILITY_MAX]; - int64_t xbzrle_cache_size; - bool complete; -diff --git a/migration.c b/migration.c -index ebfbbde..59e479d 100644 ---- a/migration.c -+++ b/migration.c -@@ -738,6 +738,11 @@ static void *buffered_file_thread(void *opaque) - DPRINTF("transferred %" PRIu64 " time_spent %" PRIu64 - " bandwidth %g max_size %" PRId64 "\n", - transferred_bytes, time_spent, bandwidth, max_size); -+ /* if we haven't sent anything, we don't want to recalculate -+ 10000 is a small enough number for our purposes */ -+ if (s->dirty_bytes_rate && transferred_bytes > 10000) { -+ s->expected_downtime = s->dirty_bytes_rate / bandwidth; -+ } - - s->bytes_xfer = 0; - sleep_time = 0; diff --git a/0105-scsi-disk-fix-VERIFY-emulation.patch b/0105-scsi-disk-fix-VERIFY-emulation.patch new file mode 100644 index 0000000..ba8f28e --- /dev/null +++ b/0105-scsi-disk-fix-VERIFY-emulation.patch @@ -0,0 +1,90 @@ +From ddc0dda3d6352e4c28e0bd11cce1d90734dce0db Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 28 Nov 2013 11:18:56 +0100 +Subject: [PATCH] scsi-disk: fix VERIFY emulation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +VERIFY emulation was completely botched (and remained botched through +all the refactorings). The command must be emulated both in check-medium +mode (BYTCHK=00, which we implement by doing nothing) and in check-bytes +mode (which we do not implement yet). Unlike WRITE AND VERIFY (which we +treat simply as WRITE with FUA bit set), VERIFY cannot be handled like +READ. In fact the device is _receiving_ data for VERIFY, not _sending_ +it like READ. + +Cc: qemu-stable@nongnu.org +Tested-by: Hervé Poussineau +Signed-off-by: Paolo Bonzini +(cherry picked from commit d97e7730816094a71cd1f19a56d7a73f77cdbf96) + +Conflicts: + hw/scsi/scsi-disk.c +--- + hw/scsi/scsi-disk.c | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 74e6a14..1fd1c26 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -1597,6 +1597,14 @@ static void scsi_disk_emulate_write_data(SCSIRequest *req) + scsi_disk_emulate_unmap(r, r->iov.iov_base); + break; + ++ case VERIFY_10: ++ case VERIFY_12: ++ case VERIFY_16: ++ if (r->req.status == -1) { ++ scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); ++ } ++ break; ++ + default: + abort(); + } +@@ -1837,6 +1845,14 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) + case UNMAP: + DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer); + break; ++ case VERIFY_10: ++ case VERIFY_12: ++ case VERIFY_16: ++ DPRINTF("Verify (bytchk %lu)\n", (r->req.buf[1] >> 1) & 3); ++ if (req->cmd.buf[1] & 6) { ++ goto illegal_request; ++ } ++ break; + case WRITE_SAME_10: + case WRITE_SAME_16: + nb_sectors = scsi_data_cdb_length(r->req.cmd.buf); +@@ -1936,10 +1952,6 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) + scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED)); + return 0; + } +- /* fallthrough */ +- case VERIFY_10: +- case VERIFY_12: +- case VERIFY_16: + DPRINTF("Write %s(sector %" PRId64 ", count %u)\n", + (command & 0xe) == 0xe ? "And Verify " : "", + r->req.cmd.lba, len); +@@ -2207,14 +2219,14 @@ static const SCSIReqOps *const scsi_disk_reqops_dispatch[256] = { + [UNMAP] = &scsi_disk_emulate_reqops, + [WRITE_SAME_10] = &scsi_disk_emulate_reqops, + [WRITE_SAME_16] = &scsi_disk_emulate_reqops, ++ [VERIFY_10] = &scsi_disk_emulate_reqops, ++ [VERIFY_12] = &scsi_disk_emulate_reqops, ++ [VERIFY_16] = &scsi_disk_emulate_reqops, + + [READ_6] = &scsi_disk_dma_reqops, + [READ_10] = &scsi_disk_dma_reqops, + [READ_12] = &scsi_disk_dma_reqops, + [READ_16] = &scsi_disk_dma_reqops, +- [VERIFY_10] = &scsi_disk_dma_reqops, +- [VERIFY_12] = &scsi_disk_dma_reqops, +- [VERIFY_16] = &scsi_disk_dma_reqops, + [WRITE_6] = &scsi_disk_dma_reqops, + [WRITE_10] = &scsi_disk_dma_reqops, + [WRITE_12] = &scsi_disk_dma_reqops, diff --git a/0106-migration-simplify-while-loop.patch b/0106-migration-simplify-while-loop.patch deleted file mode 100644 index 6034b6d..0000000 --- a/0106-migration-simplify-while-loop.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 8dd1a13b6ce0a9d83080823c8bc9d82d09100576 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:07 +0100 -Subject: [PATCH] migration: simplify while loop - -Unify the goto around the loop, with the exit condition at the end of it. -Both can be expressed as "while (ret >= 0)". - -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 5da5aad068def65b5e278a6380192d4bfe279585) ---- - migration.c | 11 +---------- - 1 file changed, 1 insertion(+), 10 deletions(-) - -diff --git a/migration.c b/migration.c -index 59e479d..71c0eec 100644 ---- a/migration.c -+++ b/migration.c -@@ -666,14 +666,9 @@ static void *buffered_file_thread(void *opaque) - qemu_mutex_lock_iothread(); - DPRINTF("beginning savevm\n"); - ret = qemu_savevm_state_begin(s->file, &s->params); -- if (ret < 0) { -- DPRINTF("failed, %d\n", ret); -- qemu_mutex_unlock_iothread(); -- goto out; -- } - qemu_mutex_unlock_iothread(); - -- while (true) { -+ while (ret >= 0) { - int64_t current_time; - uint64_t pending_size; - -@@ -754,12 +749,8 @@ static void *buffered_file_thread(void *opaque) - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } - ret = buffered_flush(s); -- if (ret < 0) { -- break; -- } - } - --out: - if (ret < 0) { - migrate_fd_error(s); - } diff --git a/0107-migration-always-use-vm_stop_force_state.patch b/0107-migration-always-use-vm_stop_force_state.patch deleted file mode 100644 index 18ad335..0000000 --- a/0107-migration-always-use-vm_stop_force_state.patch +++ /dev/null @@ -1,50 +0,0 @@ -From e78d91a594e42f11a915bd95afcaee2f4f11bc1a Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:08 +0100 -Subject: [PATCH] migration: always use vm_stop_force_state - -vm_stop_force_state does: - - if (runstate_is_running()) { - vm_stop(state); - } else { - runstate_set(state); - } - -migration.c does: - - if (runstate_is_running()) { - vm_stop(state); - } else { - vm_stop_force_state(state); - } - -The code run is the same even if we always use vm_stop_force_state in -migration.c. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 891518abd804401978e402d588733e282be960ad) ---- - migration.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/migration.c b/migration.c -index 71c0eec..d601641 100644 ---- a/migration.c -+++ b/migration.c -@@ -699,11 +699,7 @@ static void *buffered_file_thread(void *opaque) - DPRINTF("done iterating\n"); - start_time = qemu_get_clock_ms(rt_clock); - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); -- if (old_vm_running) { -- vm_stop(RUN_STATE_FINISH_MIGRATE); -- } else { -- vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); -- } -+ vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); - ret = qemu_savevm_state_complete(s->file); - if (ret < 0) { - qemu_mutex_unlock_iothread(); diff --git a/0108-migration-move-more-error-handling-to-migrate_fd_cle.patch b/0108-migration-move-more-error-handling-to-migrate_fd_cle.patch deleted file mode 100644 index 38bd7b4..0000000 --- a/0108-migration-move-more-error-handling-to-migrate_fd_cle.patch +++ /dev/null @@ -1,66 +0,0 @@ -From b259853dce28b7a8e0efe6bfedc7850821c8c76b Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:09 +0100 -Subject: [PATCH] migration: move more error handling to migrate_fd_cleanup - -The next patch will add more cases where qemu_savevm_state_cancel -needs to be called; prepare for that already, the function can be -called twice with no ill effect. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 7a2c17216cd5ae4c22844123b8e9360d517932f8) ---- - migration.c | 16 ++++++++++------ - 1 file changed, 10 insertions(+), 6 deletions(-) - -diff --git a/migration.c b/migration.c -index d601641..739e38c 100644 ---- a/migration.c -+++ b/migration.c -@@ -260,7 +260,7 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, - - /* shared migration helpers */ - --static int migrate_fd_cleanup(MigrationState *s) -+static void migrate_fd_cleanup(MigrationState *s) - { - int ret = 0; - -@@ -271,7 +271,13 @@ static int migrate_fd_cleanup(MigrationState *s) - } - - assert(s->fd == -1); -- return ret; -+ if (ret < 0 && s->state == MIG_STATE_ACTIVE) { -+ s->state = MIG_STATE_ERROR; -+ } -+ -+ if (s->state != MIG_STATE_ACTIVE) { -+ qemu_savevm_state_cancel(); -+ } - } - - void migrate_fd_error(MigrationState *s) -@@ -285,9 +291,8 @@ void migrate_fd_error(MigrationState *s) - static void migrate_fd_completed(MigrationState *s) - { - DPRINTF("setting completed state\n"); -- if (migrate_fd_cleanup(s) < 0) { -- s->state = MIG_STATE_ERROR; -- } else { -+ migrate_fd_cleanup(s); -+ if (s->state == MIG_STATE_ACTIVE) { - s->state = MIG_STATE_COMPLETED; - runstate_set(RUN_STATE_POSTMIGRATE); - } -@@ -322,7 +327,6 @@ static void migrate_fd_cancel(MigrationState *s) - - s->state = MIG_STATE_CANCELLED; - notifier_list_notify(&migration_state_notifiers, s); -- qemu_savevm_state_cancel(); - - migrate_fd_cleanup(s); - } diff --git a/0109-migration-push-qemu_savevm_state_cancel-out-of-qemu_.patch b/0109-migration-push-qemu_savevm_state_cancel-out-of-qemu_.patch deleted file mode 100644 index b9b9903..0000000 --- a/0109-migration-push-qemu_savevm_state_cancel-out-of-qemu_.patch +++ /dev/null @@ -1,70 +0,0 @@ -From bd0d732bc7d23b686f13ab377f58e227c4edc707 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:10 +0100 -Subject: [PATCH] migration: push qemu_savevm_state_cancel out of - qemu_savevm_state_* - -This is useful, because it lets us keep the cancellation callbacks -inside the big lock while pushing the others out. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 04943ebaa9e4f5f9ac080198a7b0d25c6d7ac444) ---- - savevm.c | 15 ++++----------- - 1 file changed, 4 insertions(+), 11 deletions(-) - -diff --git a/savevm.c b/savevm.c -index a8a53ef..4302903 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -1621,17 +1621,11 @@ int qemu_savevm_state_begin(QEMUFile *f, - - ret = se->ops->save_live_setup(f, se->opaque); - if (ret < 0) { -- qemu_savevm_state_cancel(); - return ret; - } - } - ret = qemu_file_get_error(f); -- if (ret != 0) { -- qemu_savevm_state_cancel(); -- } -- - return ret; -- - } - - /* -@@ -1677,9 +1671,6 @@ int qemu_savevm_state_iterate(QEMUFile *f) - return ret; - } - ret = qemu_file_get_error(f); -- if (ret != 0) { -- qemu_savevm_state_cancel(); -- } - return ret; - } - -@@ -1778,8 +1769,7 @@ static int qemu_savevm_state(QEMUFile *f) - }; - - if (qemu_savevm_state_blocked(NULL)) { -- ret = -EINVAL; -- goto out; -+ return -EINVAL; - } - - ret = qemu_savevm_state_begin(f, ¶ms); -@@ -1798,6 +1788,9 @@ out: - if (ret == 0) { - ret = qemu_file_get_error(f); - } -+ if (ret != 0) { -+ qemu_savevm_state_cancel(); -+ } - - return ret; - } diff --git a/0110-block-migration-remove-useless-calls-to-blk_mig_clea.patch b/0110-block-migration-remove-useless-calls-to-blk_mig_clea.patch deleted file mode 100644 index 3963ef2..0000000 --- a/0110-block-migration-remove-useless-calls-to-blk_mig_clea.patch +++ /dev/null @@ -1,103 +0,0 @@ -From a52c9450418c1a03aebbd95216fbd177430e2fc7 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:11 +0100 -Subject: [PATCH] block-migration: remove useless calls to blk_mig_cleanup - -Now that the cancel callback is called consistently for all errors, -we can avoid doing its work in the other callbacks. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit d418cf57a3e699746ef0bfa772bbe8c7e17cebb5) ---- - block-migration.c | 26 ++++++++------------------ - 1 file changed, 8 insertions(+), 18 deletions(-) - -diff --git a/block-migration.c b/block-migration.c -index 43ab202..e6c917d 100644 ---- a/block-migration.c -+++ b/block-migration.c -@@ -524,16 +524,10 @@ static int block_save_setup(QEMUFile *f, void *opaque) - set_dirty_tracking(1); - - ret = flush_blks(f); -- if (ret) { -- blk_mig_cleanup(); -- return ret; -- } -- - blk_mig_reset_dirty_cursor(); -- - qemu_put_be64(f, BLK_MIG_FLAG_EOS); - -- return 0; -+ return ret; - } - - static int block_save_iterate(QEMUFile *f, void *opaque) -@@ -546,7 +540,6 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - - ret = flush_blks(f); - if (ret) { -- blk_mig_cleanup(); - return ret; - } - -@@ -564,20 +557,18 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - } - } else { - ret = blk_mig_save_dirty_block(f, 1); -+ if (ret < 0) { -+ return ret; -+ } - if (ret != 0) { - /* no more dirty blocks */ - break; - } - } - } -- if (ret < 0) { -- blk_mig_cleanup(); -- return ret; -- } - - ret = flush_blks(f); - if (ret) { -- blk_mig_cleanup(); - return ret; - } - -@@ -595,7 +586,6 @@ static int block_save_complete(QEMUFile *f, void *opaque) - - ret = flush_blks(f); - if (ret) { -- blk_mig_cleanup(); - return ret; - } - -@@ -607,12 +597,11 @@ static int block_save_complete(QEMUFile *f, void *opaque) - - do { - ret = blk_mig_save_dirty_block(f, 0); -+ if (ret < 0) { -+ return ret; -+ } - } while (ret == 0); - -- blk_mig_cleanup(); -- if (ret < 0) { -- return ret; -- } - /* report completion */ - qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS); - -@@ -620,6 +609,7 @@ static int block_save_complete(QEMUFile *f, void *opaque) - - qemu_put_be64(f, BLK_MIG_FLAG_EOS); - -+ blk_mig_cleanup(); - return 0; - } - diff --git a/0111-qemu-file-pass-errno-from-qemu_fflush-via-f-last_err.patch b/0111-qemu-file-pass-errno-from-qemu_fflush-via-f-last_err.patch deleted file mode 100644 index 6a2cf60..0000000 --- a/0111-qemu-file-pass-errno-from-qemu_fflush-via-f-last_err.patch +++ /dev/null @@ -1,84 +0,0 @@ -From d35fb24839d0a0dd18b322ba8d9fbcd0b587819b Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:12 +0100 -Subject: [PATCH] qemu-file: pass errno from qemu_fflush via f->last_error - -This is done by almost all callers of qemu_fflush, move the code -directly to qemu_fflush. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 93bf21044c38134bc7d35577b675d9f2bdcb8419) ---- - savevm.c | 25 ++++++++++++------------- - 1 file changed, 12 insertions(+), 13 deletions(-) - -diff --git a/savevm.c b/savevm.c -index 4302903..a681177 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -453,13 +453,13 @@ static void qemu_file_set_error(QEMUFile *f, int ret) - /** Flushes QEMUFile buffer - * - */ --static int qemu_fflush(QEMUFile *f) -+static void qemu_fflush(QEMUFile *f) - { - int ret = 0; - -- if (!f->ops->put_buffer) -- return 0; -- -+ if (!f->ops->put_buffer) { -+ return; -+ } - if (f->is_write && f->buf_index > 0) { - ret = f->ops->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index); - if (ret >= 0) { -@@ -467,7 +467,9 @@ static int qemu_fflush(QEMUFile *f) - } - f->buf_index = 0; - } -- return ret; -+ if (ret < 0) { -+ qemu_file_set_error(f, ret); -+ } - } - - static void qemu_fill_buffer(QEMUFile *f) -@@ -518,7 +520,8 @@ int qemu_get_fd(QEMUFile *f) - int qemu_fclose(QEMUFile *f) - { - int ret; -- ret = qemu_fflush(f); -+ qemu_fflush(f); -+ ret = qemu_file_get_error(f); - - if (f->ops->close) { - int ret2 = f->ops->close(f->opaque); -@@ -560,9 +563,8 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) - buf += l; - size -= l; - if (f->buf_index >= IO_BUF_SIZE) { -- int ret = qemu_fflush(f); -- if (ret < 0) { -- qemu_file_set_error(f, ret); -+ qemu_fflush(f); -+ if (qemu_file_get_error(f)) { - break; - } - } -@@ -584,10 +586,7 @@ void qemu_put_byte(QEMUFile *f, int v) - f->buf[f->buf_index++] = v; - f->is_write = 1; - if (f->buf_index >= IO_BUF_SIZE) { -- int ret = qemu_fflush(f); -- if (ret < 0) { -- qemu_file_set_error(f, ret); -- } -+ qemu_fflush(f); - } - } - diff --git a/0112-migration-use-qemu_file_set_error-to-pass-error-code.patch b/0112-migration-use-qemu_file_set_error-to-pass-error-code.patch deleted file mode 100644 index c0f9bef..0000000 --- a/0112-migration-use-qemu_file_set_error-to-pass-error-code.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 8d5406a6a42ece0d7d9e250aabe68ea8a0e3fbf6 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:13 +0100 -Subject: [PATCH] migration: use qemu_file_set_error to pass error codes back - to qemu_savevm_state - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 47c8c17af883b5bd0f147cfcec8d7ef8ff76023b) ---- - include/sysemu/sysemu.h | 6 +++--- - savevm.c | 44 ++++++++++++++++++-------------------------- - 2 files changed, 21 insertions(+), 29 deletions(-) - -diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h -index 1d9599e..28a9221 100644 ---- a/include/sysemu/sysemu.h -+++ b/include/sysemu/sysemu.h -@@ -73,10 +73,10 @@ void do_info_snapshots(Monitor *mon, const QDict *qdict); - void qemu_announce_self(void); - - bool qemu_savevm_state_blocked(Error **errp); --int qemu_savevm_state_begin(QEMUFile *f, -- const MigrationParams *params); -+void qemu_savevm_state_begin(QEMUFile *f, -+ const MigrationParams *params); - int qemu_savevm_state_iterate(QEMUFile *f); --int qemu_savevm_state_complete(QEMUFile *f); -+void qemu_savevm_state_complete(QEMUFile *f); - void qemu_savevm_state_cancel(void); - uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size); - int qemu_loadvm_state(QEMUFile *f); -diff --git a/savevm.c b/savevm.c -index a681177..a1690b4 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -1579,8 +1579,8 @@ bool qemu_savevm_state_blocked(Error **errp) - return false; - } - --int qemu_savevm_state_begin(QEMUFile *f, -- const MigrationParams *params) -+void qemu_savevm_state_begin(QEMUFile *f, -+ const MigrationParams *params) - { - SaveStateEntry *se; - int ret; -@@ -1620,11 +1620,10 @@ int qemu_savevm_state_begin(QEMUFile *f, - - ret = se->ops->save_live_setup(f, se->opaque); - if (ret < 0) { -- return ret; -+ qemu_file_set_error(f, ret); -+ break; - } - } -- ret = qemu_file_get_error(f); -- return ret; - } - - /* -@@ -1658,6 +1657,9 @@ int qemu_savevm_state_iterate(QEMUFile *f) - ret = se->ops->save_live_iterate(f, se->opaque); - trace_savevm_section_end(se->section_id); - -+ if (ret < 0) { -+ qemu_file_set_error(f, ret); -+ } - if (ret <= 0) { - /* Do not proceed to the next vmstate before this one reported - completion of the current stage. This serializes the migration -@@ -1666,14 +1668,10 @@ int qemu_savevm_state_iterate(QEMUFile *f) - break; - } - } -- if (ret != 0) { -- return ret; -- } -- ret = qemu_file_get_error(f); - return ret; - } - --int qemu_savevm_state_complete(QEMUFile *f) -+void qemu_savevm_state_complete(QEMUFile *f) - { - SaveStateEntry *se; - int ret; -@@ -1697,7 +1695,8 @@ int qemu_savevm_state_complete(QEMUFile *f) - ret = se->ops->save_live_complete(f, se->opaque); - trace_savevm_section_end(se->section_id); - if (ret < 0) { -- return ret; -+ qemu_file_set_error(f, ret); -+ return; - } - } - -@@ -1725,8 +1724,6 @@ int qemu_savevm_state_complete(QEMUFile *f) - } - - qemu_put_byte(f, QEMU_VM_EOF); -- -- return qemu_file_get_error(f); - } - - uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size) -@@ -1771,26 +1768,21 @@ static int qemu_savevm_state(QEMUFile *f) - return -EINVAL; - } - -- ret = qemu_savevm_state_begin(f, ¶ms); -- if (ret < 0) -- goto out; -- -- do { -- ret = qemu_savevm_state_iterate(f); -- if (ret < 0) -- goto out; -- } while (ret == 0); -- -- ret = qemu_savevm_state_complete(f); -+ qemu_savevm_state_begin(f, ¶ms); -+ while (qemu_file_get_error(f) == 0) { -+ if (qemu_savevm_state_iterate(f) > 0) { -+ break; -+ } -+ } - --out: -+ ret = qemu_file_get_error(f); - if (ret == 0) { -+ qemu_savevm_state_complete(f); - ret = qemu_file_get_error(f); - } - if (ret != 0) { - qemu_savevm_state_cancel(); - } -- - return ret; - } - diff --git a/0113-qemu-file-temporarily-expose-qemu_file_set_error-and.patch b/0113-qemu-file-temporarily-expose-qemu_file_set_error-and.patch deleted file mode 100644 index 3ea3d05..0000000 --- a/0113-qemu-file-temporarily-expose-qemu_file_set_error-and.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 8c77add1c1b00cdfc3d7380aabec3add69381150 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:14 +0100 -Subject: [PATCH] qemu-file: temporarily expose qemu_file_set_error and - qemu_fflush - -Right now, migration cannot entirely rely on QEMUFile's automatic -drop of I/O after an error, because it does its "real" I/O outside -the put_buffer callback. To fix this until buffering is gone, expose -qemu_file_set_error which we will use in buffered_flush. - -Similarly, buffered_flush is not a complete flush because some data may -still reside in the QEMUFile's own buffer. This somewhat complicates the -process of closing the migration thread. Again, when buffering is gone -buffered_flush will disappear and calling qemu_fflush will not be needed; -in the meanwhile, we expose the function for use in migration.c. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 4eb938102b3d533e142de23e255e46da1326fc5a) ---- - include/migration/qemu-file.h | 2 ++ - savevm.c | 4 ++-- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h -index 46fc11d..5e0c287 100644 ---- a/include/migration/qemu-file.h -+++ b/include/migration/qemu-file.h -@@ -82,6 +82,7 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode); - int qemu_get_fd(QEMUFile *f); - int qemu_fclose(QEMUFile *f); - int64_t qemu_ftell(QEMUFile *f); -+void qemu_fflush(QEMUFile *f); - void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); - void qemu_put_byte(QEMUFile *f, int v); - -@@ -113,6 +114,7 @@ int qemu_file_rate_limit(QEMUFile *f); - int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); - int64_t qemu_file_get_rate_limit(QEMUFile *f); - int qemu_file_get_error(QEMUFile *f); -+void qemu_file_set_error(QEMUFile *f, int ret); - - static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv) - { -diff --git a/savevm.c b/savevm.c -index a1690b4..e10a045 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -443,7 +443,7 @@ int qemu_file_get_error(QEMUFile *f) - return f->last_error; - } - --static void qemu_file_set_error(QEMUFile *f, int ret) -+void qemu_file_set_error(QEMUFile *f, int ret) - { - if (f->last_error == 0) { - f->last_error = ret; -@@ -453,7 +453,7 @@ static void qemu_file_set_error(QEMUFile *f, int ret) - /** Flushes QEMUFile buffer - * - */ --static void qemu_fflush(QEMUFile *f) -+void qemu_fflush(QEMUFile *f) - { - int ret = 0; - diff --git a/0114-migration-flush-all-data-to-fd-when-buffered_flush-i.patch b/0114-migration-flush-all-data-to-fd-when-buffered_flush-i.patch deleted file mode 100644 index 7e79a3d..0000000 --- a/0114-migration-flush-all-data-to-fd-when-buffered_flush-i.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 015c261bdbb06a737b14600d62c37fef28ea9d22 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:15 +0100 -Subject: [PATCH] migration: flush all data to fd when buffered_flush is called - -Including data that resided in the QEMUFile's own buffer. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit f5821518ed6d49aae9fd0aa6169d2d74bb83054c) ---- - migration.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/migration.c b/migration.c -index 739e38c..1027b40 100644 ---- a/migration.c -+++ b/migration.c -@@ -525,6 +525,8 @@ static ssize_t buffered_flush(MigrationState *s) - - DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size); - -+ qemu_fflush(s->file); -+ - while (s->bytes_xfer < s->xfer_limit && offset < s->buffer_size) { - size_t to_send = MIN(s->buffer_size - offset, s->xfer_limit - s->bytes_xfer); - ret = migrate_fd_put_buffer(s, s->buffer + offset, to_send); diff --git a/0115-migration-use-qemu_file_set_error.patch b/0115-migration-use-qemu_file_set_error.patch deleted file mode 100644 index b058e4e..0000000 --- a/0115-migration-use-qemu_file_set_error.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 7f2725d2a64c533129504a9c9ea610169abd72f8 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:16 +0100 -Subject: [PATCH] migration: use qemu_file_set_error - -Remove the return value of buffered_flush, pass it via the error code -of s->file. Once this is done, the error can be retrieved simply -via migrate_fd_close's call to qemu_fclose. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 63dfbd7ee03185c181a0791958ec9c8337089b55) ---- - migration.c | 22 ++++++---------------- - 1 file changed, 6 insertions(+), 16 deletions(-) - -diff --git a/migration.c b/migration.c -index 1027b40..da5f175 100644 ---- a/migration.c -+++ b/migration.c -@@ -518,7 +518,7 @@ int64_t migrate_xbzrle_cache_size(void) - /* migration thread support */ - - --static ssize_t buffered_flush(MigrationState *s) -+static void buffered_flush(MigrationState *s) - { - size_t offset = 0; - ssize_t ret = 0; -@@ -545,9 +545,8 @@ static ssize_t buffered_flush(MigrationState *s) - s->buffer_size -= offset; - - if (ret < 0) { -- return ret; -+ qemu_file_set_error(s->file, ret); - } -- return offset; - } - - static int buffered_put_buffer(void *opaque, const uint8_t *buf, -@@ -586,25 +585,15 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, - static int buffered_close(void *opaque) - { - MigrationState *s = opaque; -- ssize_t ret = 0; -- int ret2; - - DPRINTF("closing\n"); - - s->xfer_limit = INT_MAX; - while (!qemu_file_get_error(s->file) && s->buffer_size) { -- ret = buffered_flush(s); -- if (ret < 0) { -- break; -- } -- } -- -- ret2 = migrate_fd_close(s); -- if (ret >= 0) { -- ret = ret2; -+ buffered_flush(s); - } - s->complete = true; -- return ret; -+ return migrate_fd_close(s); - } - - static int buffered_get_fd(void *opaque) -@@ -750,7 +739,8 @@ static void *buffered_file_thread(void *opaque) - g_usleep((initial_time + BUFFER_DELAY - current_time)*1000); - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } -- ret = buffered_flush(s); -+ buffered_flush(s); -+ ret = qemu_file_get_error(s->file); - } - - if (ret < 0) { diff --git a/0116-migration-simplify-error-handling.patch b/0116-migration-simplify-error-handling.patch deleted file mode 100644 index af7b2e7..0000000 --- a/0116-migration-simplify-error-handling.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 67f17b78f85bfa766ba9bde63148c3c171ef3426 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:17 +0100 -Subject: [PATCH] migration: simplify error handling - -Always use qemu_file_get_error to detect errors, since that is how -QEMUFile itself drops I/O after an error occurs. There is no need -to propagate and check return values all the time. - -Also remove the "complete" member, since we know that it is set (via -migrate_fd_cleanup) only when the state changes. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit dba433c03a0f5dc22a459435dd89557886298921) ---- - include/migration/migration.h | 1 - - migration.c | 46 +++++++++++++------------------------------ - 2 files changed, 14 insertions(+), 33 deletions(-) - -diff --git a/include/migration/migration.h b/include/migration/migration.h -index d121409..3e680af 100644 ---- a/include/migration/migration.h -+++ b/include/migration/migration.h -@@ -54,7 +54,6 @@ struct MigrationState - int64_t dirty_bytes_rate; - bool enabled_capabilities[MIGRATION_CAPABILITY_MAX]; - int64_t xbzrle_cache_size; -- bool complete; - }; - - void process_incoming_migration(QEMUFile *f); -diff --git a/migration.c b/migration.c -index da5f175..41a592c 100644 ---- a/migration.c -+++ b/migration.c -@@ -525,6 +525,10 @@ static void buffered_flush(MigrationState *s) - - DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size); - -+ if (qemu_file_get_error(s->file)) { -+ s->buffer_size = 0; -+ return; -+ } - qemu_fflush(s->file); - - while (s->bytes_xfer < s->xfer_limit && offset < s->buffer_size) { -@@ -592,7 +596,6 @@ static int buffered_close(void *opaque) - while (!qemu_file_get_error(s->file) && s->buffer_size) { - buffered_flush(s); - } -- s->complete = true; - return migrate_fd_close(s); - } - -@@ -656,37 +659,21 @@ static void *buffered_file_thread(void *opaque) - int64_t sleep_time = 0; - int64_t max_size = 0; - bool last_round = false; -- int ret; - - qemu_mutex_lock_iothread(); - DPRINTF("beginning savevm\n"); -- ret = qemu_savevm_state_begin(s->file, &s->params); -- qemu_mutex_unlock_iothread(); -+ qemu_savevm_state_begin(s->file, &s->params); - -- while (ret >= 0) { -+ while (s->state == MIG_STATE_ACTIVE) { - int64_t current_time; - uint64_t pending_size; - -- qemu_mutex_lock_iothread(); -- if (s->state != MIG_STATE_ACTIVE) { -- DPRINTF("put_ready returning because of non-active state\n"); -- qemu_mutex_unlock_iothread(); -- break; -- } -- if (s->complete) { -- qemu_mutex_unlock_iothread(); -- break; -- } - if (s->bytes_xfer < s->xfer_limit) { - DPRINTF("iterate\n"); - pending_size = qemu_savevm_state_pending(s->file, max_size); - DPRINTF("pending size %lu max %lu\n", pending_size, max_size); - if (pending_size && pending_size >= max_size) { -- ret = qemu_savevm_state_iterate(s->file); -- if (ret < 0) { -- qemu_mutex_unlock_iothread(); -- break; -- } -+ qemu_savevm_state_iterate(s->file); - } else { - int old_vm_running = runstate_is_running(); - int64_t start_time, end_time; -@@ -695,13 +682,8 @@ static void *buffered_file_thread(void *opaque) - start_time = qemu_get_clock_ms(rt_clock); - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); - vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); -- ret = qemu_savevm_state_complete(s->file); -- if (ret < 0) { -- qemu_mutex_unlock_iothread(); -- break; -- } else { -- migrate_fd_completed(s); -- } -+ qemu_savevm_state_complete(s->file); -+ migrate_fd_completed(s); - end_time = qemu_get_clock_ms(rt_clock); - s->total_time = end_time - s->total_time; - s->downtime = end_time - start_time; -@@ -740,12 +722,13 @@ static void *buffered_file_thread(void *opaque) - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } - buffered_flush(s); -- ret = qemu_file_get_error(s->file); -+ qemu_mutex_lock_iothread(); -+ if (qemu_file_get_error(s->file)) { -+ migrate_fd_error(s); -+ } - } - -- if (ret < 0) { -- migrate_fd_error(s); -- } -+ qemu_mutex_unlock_iothread(); - g_free(s->buffer); - return NULL; - } -@@ -770,7 +753,6 @@ void migrate_fd_connect(MigrationState *s) - s->expected_downtime = max_downtime/1000000; - - s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; -- s->complete = false; - - s->file = qemu_fopen_ops(s, &buffered_file_ops); - diff --git a/0117-migration-do-not-nest-flushing-of-device-data.patch b/0117-migration-do-not-nest-flushing-of-device-data.patch deleted file mode 100644 index fdc5792..0000000 --- a/0117-migration-do-not-nest-flushing-of-device-data.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 907358d71215fdc486c6e70de9b16cfefc88303b Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:18 +0100 -Subject: [PATCH] migration: do not nest flushing of device data - -Completion of migration is currently done with a "nested" loop that -invokes buffered_flush: migrate_fd_completed is called by -buffered_file_thread, which calls migrate_fd_cleanup, which calls -buffered_close (via qemu_fclose), which flushes the buffer. - -Simplify this, by reusing the buffered_flush call of buffered_file_thread. -Then if qemu_savevm_state_complete was called, and the buffer is empty -(including the QEMUFile buffer, for which we need the previous patch), we -are done. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit a3fa1d78cbae2259491b17689812edcb643a3b30) ---- - migration.c | 55 ++++++++++++++++++++++++------------------------------- - 1 file changed, 24 insertions(+), 31 deletions(-) - -diff --git a/migration.c b/migration.c -index 41a592c..57fceb6d 100644 ---- a/migration.c -+++ b/migration.c -@@ -262,41 +262,34 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, - - static void migrate_fd_cleanup(MigrationState *s) - { -- int ret = 0; -- - if (s->file) { - DPRINTF("closing file\n"); -- ret = qemu_fclose(s->file); -+ qemu_fclose(s->file); - s->file = NULL; - } - - assert(s->fd == -1); -- if (ret < 0 && s->state == MIG_STATE_ACTIVE) { -- s->state = MIG_STATE_ERROR; -- } -+ assert(s->state != MIG_STATE_ACTIVE); - -- if (s->state != MIG_STATE_ACTIVE) { -+ if (s->state != MIG_STATE_COMPLETED) { - qemu_savevm_state_cancel(); - } -+ -+ notifier_list_notify(&migration_state_notifiers, s); - } - - void migrate_fd_error(MigrationState *s) - { - DPRINTF("setting error state\n"); - s->state = MIG_STATE_ERROR; -- notifier_list_notify(&migration_state_notifiers, s); - migrate_fd_cleanup(s); - } - - static void migrate_fd_completed(MigrationState *s) - { - DPRINTF("setting completed state\n"); -+ s->state = MIG_STATE_COMPLETED; - migrate_fd_cleanup(s); -- if (s->state == MIG_STATE_ACTIVE) { -- s->state = MIG_STATE_COMPLETED; -- runstate_set(RUN_STATE_POSTMIGRATE); -- } -- notifier_list_notify(&migration_state_notifiers, s); - } - - static ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data, -@@ -326,8 +319,6 @@ static void migrate_fd_cancel(MigrationState *s) - DPRINTF("cancelling migration\n"); - - s->state = MIG_STATE_CANCELLED; -- notifier_list_notify(&migration_state_notifiers, s); -- - migrate_fd_cleanup(s); - } - -@@ -592,10 +583,6 @@ static int buffered_close(void *opaque) - - DPRINTF("closing\n"); - -- s->xfer_limit = INT_MAX; -- while (!qemu_file_get_error(s->file) && s->buffer_size) { -- buffered_flush(s); -- } - return migrate_fd_close(s); - } - -@@ -658,6 +645,8 @@ static void *buffered_file_thread(void *opaque) - int64_t initial_time = qemu_get_clock_ms(rt_clock); - int64_t sleep_time = 0; - int64_t max_size = 0; -+ int64_t start_time = initial_time; -+ bool old_vm_running = false; - bool last_round = false; - - qemu_mutex_lock_iothread(); -@@ -675,23 +664,13 @@ static void *buffered_file_thread(void *opaque) - if (pending_size && pending_size >= max_size) { - qemu_savevm_state_iterate(s->file); - } else { -- int old_vm_running = runstate_is_running(); -- int64_t start_time, end_time; -- - DPRINTF("done iterating\n"); - start_time = qemu_get_clock_ms(rt_clock); - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); -+ old_vm_running = runstate_is_running(); - vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); -+ s->xfer_limit = INT_MAX; - qemu_savevm_state_complete(s->file); -- migrate_fd_completed(s); -- end_time = qemu_get_clock_ms(rt_clock); -- s->total_time = end_time - s->total_time; -- s->downtime = end_time - start_time; -- if (s->state != MIG_STATE_COMPLETED) { -- if (old_vm_running) { -- vm_start(); -- } -- } - last_round = true; - } - } -@@ -725,6 +704,20 @@ static void *buffered_file_thread(void *opaque) - qemu_mutex_lock_iothread(); - if (qemu_file_get_error(s->file)) { - migrate_fd_error(s); -+ } else if (last_round && s->buffer_size == 0) { -+ migrate_fd_completed(s); -+ } -+ } -+ -+ if (s->state == MIG_STATE_COMPLETED) { -+ int64_t end_time = qemu_get_clock_ms(rt_clock); -+ s->total_time = end_time - s->total_time; -+ s->downtime = end_time - start_time; -+ runstate_set(RUN_STATE_POSTMIGRATE); -+ } else { -+ if (old_vm_running) { -+ assert(last_round); -+ vm_start(); - } - } - diff --git a/0118-migration-add-migrate_set_state-tracepoint.patch b/0118-migration-add-migrate_set_state-tracepoint.patch deleted file mode 100644 index e196be0..0000000 --- a/0118-migration-add-migrate_set_state-tracepoint.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 12a2075cf44c3234ba3efd7afb7a924ff39ba441 Mon Sep 17 00:00:00 2001 -From: Kazuya Saito -Date: Fri, 22 Feb 2013 17:36:19 +0100 -Subject: [PATCH] migration: add migrate_set_state tracepoint - -Signed-off-by: Kazuya Saito -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit c09e5bb1d88ef38986bac7c6ed59dbd732cc4771) ---- - migration.c | 9 ++++++++- - trace-events | 3 +++ - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/migration.c b/migration.c -index 57fceb6d..c0a9239 100644 ---- a/migration.c -+++ b/migration.c -@@ -23,6 +23,7 @@ - #include "migration/block.h" - #include "qemu/thread.h" - #include "qmp-commands.h" -+#include "trace.h" - - //#define DEBUG_MIGRATION - -@@ -282,6 +283,7 @@ void migrate_fd_error(MigrationState *s) - { - DPRINTF("setting error state\n"); - s->state = MIG_STATE_ERROR; -+ trace_migrate_set_state(MIG_STATE_ERROR); - migrate_fd_cleanup(s); - } - -@@ -289,6 +291,7 @@ static void migrate_fd_completed(MigrationState *s) - { - DPRINTF("setting completed state\n"); - s->state = MIG_STATE_COMPLETED; -+ trace_migrate_set_state(MIG_STATE_COMPLETED); - migrate_fd_cleanup(s); - } - -@@ -319,6 +322,7 @@ static void migrate_fd_cancel(MigrationState *s) - DPRINTF("cancelling migration\n"); - - s->state = MIG_STATE_CANCELLED; -+ trace_migrate_set_state(MIG_STATE_CANCELLED); - migrate_fd_cleanup(s); - } - -@@ -377,8 +381,9 @@ static MigrationState *migrate_init(const MigrationParams *params) - - s->bandwidth_limit = bandwidth_limit; - s->state = MIG_STATE_SETUP; -- s->total_time = qemu_get_clock_ms(rt_clock); -+ trace_migrate_set_state(MIG_STATE_SETUP); - -+ s->total_time = qemu_get_clock_ms(rt_clock); - return s; - } - -@@ -738,6 +743,8 @@ static const QEMUFileOps buffered_file_ops = { - void migrate_fd_connect(MigrationState *s) - { - s->state = MIG_STATE_ACTIVE; -+ trace_migrate_set_state(MIG_STATE_ACTIVE); -+ - s->bytes_xfer = 0; - s->buffer = NULL; - s->buffer_size = 0; -diff --git a/trace-events b/trace-events -index 167f481..614c4ef 100644 ---- a/trace-events -+++ b/trace-events -@@ -1091,3 +1091,6 @@ css_io_interrupt(int cssid, int ssid, int schid, uint32_t intparm, uint8_t isc, - # hw/s390x/virtio-ccw.c - virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code) "VIRTIO-CCW: %x.%x.%04x: interpret command %x" - virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char *devno_mode) "VIRTIO-CCW: add subchannel %x.%x.%04x, devno %04x (%s)" -+ -+# migration.c -+migrate_set_state(int new_state) "new state %d" diff --git a/0119-migration-prepare-to-access-s-state-outside-critical.patch b/0119-migration-prepare-to-access-s-state-outside-critical.patch deleted file mode 100644 index a5fac6b..0000000 --- a/0119-migration-prepare-to-access-s-state-outside-critical.patch +++ /dev/null @@ -1,126 +0,0 @@ -From b61e15d1ead74c97c9fa709f6d2868529bae1098 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:20 +0100 -Subject: [PATCH] migration: prepare to access s->state outside critical - sections - -Accessing s->state outside the big QEMU lock will simplify a bit the -locking/unlocking of the iothread lock. - -We need to keep the lock in migrate_fd_error and migrate_fd_completed, -however, because they call migrate_fd_cleanup. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit f4410a5d9926886c36d9fa9fdd969d0469d62724) ---- - migration.c | 33 +++++++++++++++++++++------------ - 1 file changed, 21 insertions(+), 12 deletions(-) - -diff --git a/migration.c b/migration.c -index c0a9239..e844b2c 100644 ---- a/migration.c -+++ b/migration.c -@@ -279,19 +279,25 @@ static void migrate_fd_cleanup(MigrationState *s) - notifier_list_notify(&migration_state_notifiers, s); - } - -+static void migrate_finish_set_state(MigrationState *s, int new_state) -+{ -+ if (__sync_val_compare_and_swap(&s->state, MIG_STATE_ACTIVE, -+ new_state) == new_state) { -+ trace_migrate_set_state(new_state); -+ } -+} -+ - void migrate_fd_error(MigrationState *s) - { - DPRINTF("setting error state\n"); -- s->state = MIG_STATE_ERROR; -- trace_migrate_set_state(MIG_STATE_ERROR); -+ migrate_finish_set_state(s, MIG_STATE_ERROR); - migrate_fd_cleanup(s); - } - - static void migrate_fd_completed(MigrationState *s) - { - DPRINTF("setting completed state\n"); -- s->state = MIG_STATE_COMPLETED; -- trace_migrate_set_state(MIG_STATE_COMPLETED); -+ migrate_finish_set_state(s, MIG_STATE_COMPLETED); - migrate_fd_cleanup(s); - } - -@@ -316,13 +322,9 @@ static ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data, - - static void migrate_fd_cancel(MigrationState *s) - { -- if (s->state != MIG_STATE_ACTIVE) -- return; -- - DPRINTF("cancelling migration\n"); - -- s->state = MIG_STATE_CANCELLED; -- trace_migrate_set_state(MIG_STATE_CANCELLED); -+ migrate_finish_set_state(s, MIG_STATE_CANCELLED); - migrate_fd_cleanup(s); - } - -@@ -657,12 +659,14 @@ static void *buffered_file_thread(void *opaque) - qemu_mutex_lock_iothread(); - DPRINTF("beginning savevm\n"); - qemu_savevm_state_begin(s->file, &s->params); -+ qemu_mutex_unlock_iothread(); - - while (s->state == MIG_STATE_ACTIVE) { - int64_t current_time; - uint64_t pending_size; - - if (s->bytes_xfer < s->xfer_limit) { -+ qemu_mutex_lock_iothread(); - DPRINTF("iterate\n"); - pending_size = qemu_savevm_state_pending(s->file, max_size); - DPRINTF("pending size %lu max %lu\n", pending_size, max_size); -@@ -678,8 +682,9 @@ static void *buffered_file_thread(void *opaque) - qemu_savevm_state_complete(s->file); - last_round = true; - } -+ qemu_mutex_unlock_iothread(); - } -- qemu_mutex_unlock_iothread(); -+ - current_time = qemu_get_clock_ms(rt_clock); - if (current_time >= initial_time + BUFFER_DELAY) { - uint64_t transferred_bytes = s->bytes_xfer; -@@ -706,14 +711,18 @@ static void *buffered_file_thread(void *opaque) - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } - buffered_flush(s); -- qemu_mutex_lock_iothread(); - if (qemu_file_get_error(s->file)) { -+ qemu_mutex_lock_iothread(); - migrate_fd_error(s); -+ qemu_mutex_unlock_iothread(); - } else if (last_round && s->buffer_size == 0) { -+ qemu_mutex_lock_iothread(); - migrate_fd_completed(s); -+ qemu_mutex_unlock_iothread(); - } - } - -+ qemu_mutex_lock_iothread(); - if (s->state == MIG_STATE_COMPLETED) { - int64_t end_time = qemu_get_clock_ms(rt_clock); - s->total_time = end_time - s->total_time; -@@ -725,8 +734,8 @@ static void *buffered_file_thread(void *opaque) - vm_start(); - } - } -- - qemu_mutex_unlock_iothread(); -+ - g_free(s->buffer); - return NULL; - } diff --git a/0120-migration-cleanup-migration-including-thread-in-the-.patch b/0120-migration-cleanup-migration-including-thread-in-the-.patch deleted file mode 100644 index 87c1b80..0000000 --- a/0120-migration-cleanup-migration-including-thread-in-the-.patch +++ /dev/null @@ -1,129 +0,0 @@ -From bce1e693cdf25a98c120882197c9fcce975fb039 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:21 +0100 -Subject: [PATCH] migration: cleanup migration (including thread) in the - iothread - -Perform final cleanup in a bottom half, and add joining the thread to -the series of cleanup actions. - -migrate_fd_error remains for connection error, but it doesn't need -to cleanup anything anymore. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit bb1fadc444ff967554c41d96cb9dde110e8aece9) ---- - include/migration/migration.h | 1 + - migration.c | 38 ++++++++++++++++++++------------------ - 2 files changed, 21 insertions(+), 18 deletions(-) - -diff --git a/include/migration/migration.h b/include/migration/migration.h -index 3e680af..ed20bed 100644 ---- a/include/migration/migration.h -+++ b/include/migration/migration.h -@@ -38,6 +38,7 @@ struct MigrationState - size_t buffer_size; - size_t buffer_capacity; - QemuThread thread; -+ QEMUBH *cleanup_bh; - - QEMUFile *file; - int fd; -diff --git a/migration.c b/migration.c -index e844b2c..437475b 100644 ---- a/migration.c -+++ b/migration.c -@@ -261,8 +261,13 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, - - /* shared migration helpers */ - --static void migrate_fd_cleanup(MigrationState *s) -+static void migrate_fd_cleanup(void *opaque) - { -+ MigrationState *s = opaque; -+ -+ qemu_bh_delete(s->cleanup_bh); -+ s->cleanup_bh = NULL; -+ - if (s->file) { - DPRINTF("closing file\n"); - qemu_fclose(s->file); -@@ -290,15 +295,10 @@ static void migrate_finish_set_state(MigrationState *s, int new_state) - void migrate_fd_error(MigrationState *s) - { - DPRINTF("setting error state\n"); -- migrate_finish_set_state(s, MIG_STATE_ERROR); -- migrate_fd_cleanup(s); --} -- --static void migrate_fd_completed(MigrationState *s) --{ -- DPRINTF("setting completed state\n"); -- migrate_finish_set_state(s, MIG_STATE_COMPLETED); -- migrate_fd_cleanup(s); -+ assert(s->file == NULL); -+ s->state = MIG_STATE_ERROR; -+ trace_migrate_set_state(MIG_STATE_ERROR); -+ notifier_list_notify(&migration_state_notifiers, s); - } - - static ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data, -@@ -325,7 +325,6 @@ static void migrate_fd_cancel(MigrationState *s) - DPRINTF("cancelling migration\n"); - - migrate_finish_set_state(s, MIG_STATE_CANCELLED); -- migrate_fd_cleanup(s); - } - - int migrate_fd_close(MigrationState *s) -@@ -590,6 +589,11 @@ static int buffered_close(void *opaque) - - DPRINTF("closing\n"); - -+ qemu_mutex_unlock_iothread(); -+ qemu_thread_join(&s->thread); -+ qemu_mutex_lock_iothread(); -+ assert(s->state != MIG_STATE_ACTIVE); -+ - return migrate_fd_close(s); - } - -@@ -712,13 +716,9 @@ static void *buffered_file_thread(void *opaque) - } - buffered_flush(s); - if (qemu_file_get_error(s->file)) { -- qemu_mutex_lock_iothread(); -- migrate_fd_error(s); -- qemu_mutex_unlock_iothread(); -+ migrate_finish_set_state(s, MIG_STATE_ERROR); - } else if (last_round && s->buffer_size == 0) { -- qemu_mutex_lock_iothread(); -- migrate_fd_completed(s); -- qemu_mutex_unlock_iothread(); -+ migrate_finish_set_state(s, MIG_STATE_COMPLETED); - } - } - -@@ -734,6 +734,7 @@ static void *buffered_file_thread(void *opaque) - vm_start(); - } - } -+ qemu_bh_schedule(s->cleanup_bh); - qemu_mutex_unlock_iothread(); - - g_free(s->buffer); -@@ -763,9 +764,10 @@ void migrate_fd_connect(MigrationState *s) - - s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; - -+ s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); - s->file = qemu_fopen_ops(s, &buffered_file_ops); - - qemu_thread_create(&s->thread, buffered_file_thread, s, -- QEMU_THREAD_DETACHED); -+ QEMU_THREAD_JOINABLE); - notifier_list_notify(&migration_state_notifiers, s); - } diff --git a/0121-block-migration-remove-variables-that-are-never-read.patch b/0121-block-migration-remove-variables-that-are-never-read.patch deleted file mode 100644 index 9ac176c..0000000 --- a/0121-block-migration-remove-variables-that-are-never-read.patch +++ /dev/null @@ -1,70 +0,0 @@ -From b4800390037c71ffa12d691d3410327bc3eb826e Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:22 +0100 -Subject: [PATCH] block-migration: remove variables that are never read - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit a55ce1c851b5802569fb00b2a645a73c03fd7c86) ---- - block-migration.c | 13 ------------- - 1 file changed, 13 deletions(-) - -diff --git a/block-migration.c b/block-migration.c -index e6c917d..e72f322 100644 ---- a/block-migration.c -+++ b/block-migration.c -@@ -50,7 +50,6 @@ typedef struct BlkMigDevState { - int64_t cur_dirty; - int64_t completed_sectors; - int64_t total_sectors; -- int64_t dirty; - QSIMPLEQ_ENTRY(BlkMigDevState) entry; - unsigned long *aio_bitmap; - } BlkMigDevState; -@@ -78,7 +77,6 @@ typedef struct BlkMigState { - int64_t total_sector_sum; - int prev_progress; - int bulk_completed; -- long double prev_time_offset; - } BlkMigState; - - static BlkMigState block_mig_state; -@@ -179,13 +177,10 @@ static void alloc_aio_bitmap(BlkMigDevState *bmds) - - static void blk_mig_read_cb(void *opaque, int ret) - { -- long double curr_time = qemu_get_clock_ns(rt_clock); - BlkMigBlock *blk = opaque; - - blk->ret = ret; - -- block_mig_state.prev_time_offset = curr_time; -- - QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry); - bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0); - -@@ -236,10 +231,6 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; - qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); - -- if (block_mig_state.submitted == 0) { -- block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock); -- } -- - blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); - block_mig_state.submitted++; -@@ -382,10 +373,6 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, - blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; - qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); - -- if (block_mig_state.submitted == 0) { -- block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock); -- } -- - blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); - block_mig_state.submitted++; diff --git a/0122-block-migration-small-preparatory-changes-for-lockin.patch b/0122-block-migration-small-preparatory-changes-for-lockin.patch deleted file mode 100644 index d3e23f3..0000000 --- a/0122-block-migration-small-preparatory-changes-for-lockin.patch +++ /dev/null @@ -1,88 +0,0 @@ -From b91507ad365c4672fb8c8217b9f37ce5c151e229 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:23 +0100 -Subject: [PATCH] block-migration: small preparatory changes for locking - -Some small changes that will simplify the positioning of lock/unlock -primitives. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 13197e3cbaba0ba693dd2855a32182ca584fa97e) ---- - block-migration.c | 26 +++++++++++++++----------- - 1 file changed, 15 insertions(+), 11 deletions(-) - -diff --git a/block-migration.c b/block-migration.c -index e72f322..9a40edd 100644 ---- a/block-migration.c -+++ b/block-migration.c -@@ -231,9 +231,10 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; - qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); - -+ block_mig_state.submitted++; -+ - blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); -- block_mig_state.submitted++; - - bdrv_reset_dirty(bs, cur_sector, nr_sectors); - bmds->cur_sector = cur_sector + nr_sectors; -@@ -440,9 +441,10 @@ static int flush_blks(QEMUFile *f) - ret = blk->ret; - break; - } -- blk_send(f, blk); - - QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry); -+ blk_send(f, blk); -+ - g_free(blk->buf); - g_free(blk); - -@@ -542,15 +544,16 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - /* finished saving bulk on all devices */ - block_mig_state.bulk_completed = 1; - } -+ ret = 0; - } else { - ret = blk_mig_save_dirty_block(f, 1); -- if (ret < 0) { -- return ret; -- } -- if (ret != 0) { -- /* no more dirty blocks */ -- break; -- } -+ } -+ if (ret < 0) { -+ return ret; -+ } -+ if (ret != 0) { -+ /* no more dirty blocks */ -+ break; - } - } - -@@ -560,7 +563,6 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - } - - qemu_put_be64(f, BLK_MIG_FLAG_EOS); -- - return qemu_ftell(f) - last_ftell; - } - -@@ -603,7 +605,9 @@ static int block_save_complete(QEMUFile *f, void *opaque) - static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) - { - /* Estimate pending number of bytes to send */ -- uint64_t pending = get_remaining_dirty() + -+ uint64_t pending; -+ -+ pending = get_remaining_dirty() + - block_mig_state.submitted * BLOCK_SIZE + - block_mig_state.read_done * BLOCK_SIZE; - diff --git a/0123-block-migration-document-usage-of-state-across-threa.patch b/0123-block-migration-document-usage-of-state-across-threa.patch deleted file mode 100644 index 643e07b..0000000 --- a/0123-block-migration-document-usage-of-state-across-threa.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 4c62f3e4b8f0c014306c4e5dae4eb8c59289d562 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:24 +0100 -Subject: [PATCH] block-migration: document usage of state across threads - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 323920c4eac01de74cf2b5e941c97ca9b2d36b7f) ---- - block-migration.c | 23 ++++++++++++++++++----- - 1 file changed, 18 insertions(+), 5 deletions(-) - -diff --git a/block-migration.c b/block-migration.c -index 9a40edd..d62a8b8 100644 ---- a/block-migration.c -+++ b/block-migration.c -@@ -43,18 +43,24 @@ - #endif - - typedef struct BlkMigDevState { -+ /* Written during setup phase. Can be read without a lock. */ - BlockDriverState *bs; -- int bulk_completed; - int shared_base; -- int64_t cur_sector; -- int64_t cur_dirty; -- int64_t completed_sectors; - int64_t total_sectors; - QSIMPLEQ_ENTRY(BlkMigDevState) entry; -+ -+ /* Only used by migration thread. Does not need a lock. */ -+ int bulk_completed; -+ int64_t cur_sector; -+ int64_t cur_dirty; -+ -+ /* Protected by iothread lock. */ - unsigned long *aio_bitmap; -+ int64_t completed_sectors; - } BlkMigDevState; - - typedef struct BlkMigBlock { -+ /* Only used by migration thread. */ - uint8_t *buf; - BlkMigDevState *bmds; - int64_t sector; -@@ -62,19 +68,26 @@ typedef struct BlkMigBlock { - struct iovec iov; - QEMUIOVector qiov; - BlockDriverAIOCB *aiocb; -+ -+ /* Protected by iothread lock. */ - int ret; - QSIMPLEQ_ENTRY(BlkMigBlock) entry; - } BlkMigBlock; - - typedef struct BlkMigState { -+ /* Written during setup phase. Can be read without a lock. */ - int blk_enable; - int shared_base; - QSIMPLEQ_HEAD(bmds_list, BlkMigDevState) bmds_list; -+ int64_t total_sector_sum; -+ -+ /* Protected by iothread lock. */ - QSIMPLEQ_HEAD(blk_list, BlkMigBlock) blk_list; - int submitted; - int read_done; -+ -+ /* Only used by migration thread. Does not need a lock. */ - int transferred; -- int64_t total_sector_sum; - int prev_progress; - int bulk_completed; - } BlkMigState; diff --git a/0124-block-migration-add-lock.patch b/0124-block-migration-add-lock.patch deleted file mode 100644 index f536e0c..0000000 --- a/0124-block-migration-add-lock.patch +++ /dev/null @@ -1,279 +0,0 @@ -From f53959ca0d677a2ff0bf7243faeb2174f83268dc Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:25 +0100 -Subject: [PATCH] block-migration: add lock - -Some state is shared between the block migration code and its AIO -callbacks. Once block migration will run outside the iothread, -the block migration code and the AIO callbacks will be able to -run concurrently. Protect the critical sections with a separate -lock. Do the same for completed_sectors, which can be used from -the monitor. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 52e850dea988585c3d693fd9cd4a4c38968d89b8) ---- - block-migration.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++--- - include/qemu/atomic.h | 1 + - 2 files changed, 52 insertions(+), 3 deletions(-) - -diff --git a/block-migration.c b/block-migration.c -index d62a8b8..b726c6c 100644 ---- a/block-migration.c -+++ b/block-migration.c -@@ -54,7 +54,7 @@ typedef struct BlkMigDevState { - int64_t cur_sector; - int64_t cur_dirty; - -- /* Protected by iothread lock. */ -+ /* Protected by block migration lock. */ - unsigned long *aio_bitmap; - int64_t completed_sectors; - } BlkMigDevState; -@@ -69,7 +69,7 @@ typedef struct BlkMigBlock { - QEMUIOVector qiov; - BlockDriverAIOCB *aiocb; - -- /* Protected by iothread lock. */ -+ /* Protected by block migration lock. */ - int ret; - QSIMPLEQ_ENTRY(BlkMigBlock) entry; - } BlkMigBlock; -@@ -81,7 +81,7 @@ typedef struct BlkMigState { - QSIMPLEQ_HEAD(bmds_list, BlkMigDevState) bmds_list; - int64_t total_sector_sum; - -- /* Protected by iothread lock. */ -+ /* Protected by lock. */ - QSIMPLEQ_HEAD(blk_list, BlkMigBlock) blk_list; - int submitted; - int read_done; -@@ -90,10 +90,23 @@ typedef struct BlkMigState { - int transferred; - int prev_progress; - int bulk_completed; -+ -+ /* Lock must be taken _inside_ the iothread lock. */ -+ QemuMutex lock; - } BlkMigState; - - static BlkMigState block_mig_state; - -+static void blk_mig_lock(void) -+{ -+ qemu_mutex_lock(&block_mig_state.lock); -+} -+ -+static void blk_mig_unlock(void) -+{ -+ qemu_mutex_unlock(&block_mig_state.lock); -+} -+ - static void blk_send(QEMUFile *f, BlkMigBlock * blk) - { - int len; -@@ -120,9 +133,11 @@ uint64_t blk_mig_bytes_transferred(void) - BlkMigDevState *bmds; - uint64_t sum = 0; - -+ blk_mig_lock(); - QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { - sum += bmds->completed_sectors; - } -+ blk_mig_unlock(); - return sum << BDRV_SECTOR_BITS; - } - -@@ -142,6 +157,9 @@ uint64_t blk_mig_bytes_total(void) - return sum << BDRV_SECTOR_BITS; - } - -+ -+/* Called with migration lock held. */ -+ - static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector) - { - int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; -@@ -154,6 +172,8 @@ static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector) - } - } - -+/* Called with migration lock held. */ -+ - static void bmds_set_aio_inflight(BlkMigDevState *bmds, int64_t sector_num, - int nb_sectors, int set) - { -@@ -188,10 +208,13 @@ static void alloc_aio_bitmap(BlkMigDevState *bmds) - bmds->aio_bitmap = g_malloc0(bitmap_size); - } - -+/* Never hold migration lock when yielding to the main loop! */ -+ - static void blk_mig_read_cb(void *opaque, int ret) - { - BlkMigBlock *blk = opaque; - -+ blk_mig_lock(); - blk->ret = ret; - - QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry); -@@ -200,6 +223,7 @@ static void blk_mig_read_cb(void *opaque, int ret) - block_mig_state.submitted--; - block_mig_state.read_done++; - assert(block_mig_state.submitted >= 0); -+ blk_mig_unlock(); - } - - static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) -@@ -244,7 +268,9 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; - qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); - -+ blk_mig_lock(); - block_mig_state.submitted++; -+ blk_mig_unlock(); - - blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); -@@ -366,8 +392,12 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, - int ret = -EIO; - - for (sector = bmds->cur_dirty; sector < bmds->total_sectors;) { -+ blk_mig_lock(); - if (bmds_aio_inflight(bmds, sector)) { -+ blk_mig_unlock(); - bdrv_drain_all(); -+ } else { -+ blk_mig_unlock(); - } - if (bdrv_get_dirty(bmds->bs, sector)) { - -@@ -389,8 +419,11 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, - - blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); -+ -+ blk_mig_lock(); - block_mig_state.submitted++; - bmds_set_aio_inflight(bmds, sector, nr_sectors, 1); -+ blk_mig_unlock(); - } else { - ret = bdrv_read(bmds->bs, sector, blk->buf, nr_sectors); - if (ret < 0) { -@@ -446,6 +479,7 @@ static int flush_blks(QEMUFile *f) - __FUNCTION__, block_mig_state.submitted, block_mig_state.read_done, - block_mig_state.transferred); - -+ blk_mig_lock(); - while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) { - if (qemu_file_rate_limit(f)) { - break; -@@ -456,7 +490,9 @@ static int flush_blks(QEMUFile *f) - } - - QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry); -+ blk_mig_unlock(); - blk_send(f, blk); -+ blk_mig_lock(); - - g_free(blk->buf); - g_free(blk); -@@ -465,6 +501,7 @@ static int flush_blks(QEMUFile *f) - block_mig_state.transferred++; - assert(block_mig_state.read_done >= 0); - } -+ blk_mig_unlock(); - - DPRINTF("%s Exit submitted %d read_done %d transferred %d\n", __FUNCTION__, - block_mig_state.submitted, block_mig_state.read_done, -@@ -493,6 +530,7 @@ static void blk_mig_cleanup(void) - - set_dirty_tracking(0); - -+ blk_mig_lock(); - while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) { - QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry); - bdrv_set_in_use(bmds->bs, 0); -@@ -506,6 +544,7 @@ static void blk_mig_cleanup(void) - g_free(blk->buf); - g_free(blk); - } -+ blk_mig_unlock(); - } - - static void block_migration_cancel(void *opaque) -@@ -548,9 +587,11 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - blk_mig_reset_dirty_cursor(); - - /* control the rate of transfer */ -+ blk_mig_lock(); - while ((block_mig_state.submitted + - block_mig_state.read_done) * BLOCK_SIZE < - qemu_file_get_rate_limit(f)) { -+ blk_mig_unlock(); - if (block_mig_state.bulk_completed == 0) { - /* first finish the bulk phase */ - if (blk_mig_save_bulked_block(f) == 0) { -@@ -564,11 +605,13 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - if (ret < 0) { - return ret; - } -+ blk_mig_lock(); - if (ret != 0) { - /* no more dirty blocks */ - break; - } - } -+ blk_mig_unlock(); - - ret = flush_blks(f); - if (ret) { -@@ -595,7 +638,9 @@ static int block_save_complete(QEMUFile *f, void *opaque) - - /* we know for sure that save bulk is completed and - all async read completed */ -+ blk_mig_lock(); - assert(block_mig_state.submitted == 0); -+ blk_mig_unlock(); - - do { - ret = blk_mig_save_dirty_block(f, 0); -@@ -620,6 +665,7 @@ static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) - /* Estimate pending number of bytes to send */ - uint64_t pending; - -+ blk_mig_lock(); - pending = get_remaining_dirty() + - block_mig_state.submitted * BLOCK_SIZE + - block_mig_state.read_done * BLOCK_SIZE; -@@ -628,6 +674,7 @@ static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) - if (pending == 0 && !block_mig_state.bulk_completed) { - pending = BLOCK_SIZE; - } -+ blk_mig_unlock(); - - DPRINTF("Enter save live pending %" PRIu64 "\n", pending); - return pending; -@@ -739,6 +786,7 @@ void blk_mig_init(void) - { - QSIMPLEQ_INIT(&block_mig_state.bmds_list); - QSIMPLEQ_INIT(&block_mig_state.blk_list); -+ qemu_mutex_init(&block_mig_state.lock); - - register_savevm_live(NULL, "block", 0, 1, &savevm_block_handlers, - &block_mig_state); -diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h -index 96a194b..10becb6 100644 ---- a/include/qemu/atomic.h -+++ b/include/qemu/atomic.h -@@ -16,6 +16,7 @@ - */ - #define smp_wmb() barrier() - #define smp_rmb() barrier() -+ - /* - * We use GCC builtin if it's available, as that can use - * mfence on 32 bit as well, e.g. if built with -march=pentium-m. diff --git a/0125-migration-reorder-SaveVMHandlers-members.patch b/0125-migration-reorder-SaveVMHandlers-members.patch deleted file mode 100644 index be21f40..0000000 --- a/0125-migration-reorder-SaveVMHandlers-members.patch +++ /dev/null @@ -1,40 +0,0 @@ -From aa1e411294714429d6d4eb66bdb4266f65a01d1f Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:26 +0100 -Subject: [PATCH] migration: reorder SaveVMHandlers members - -This groups together the callbacks that later will have similar -locking rules. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 8c8de19d93444536d3291e6ab83e2bcf61dd2d0c) ---- - include/migration/vmstate.h | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h -index f27276c..6229569 100644 ---- a/include/migration/vmstate.h -+++ b/include/migration/vmstate.h -@@ -32,13 +32,15 @@ typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id); - typedef struct SaveVMHandlers { - void (*set_params)(const MigrationParams *params, void * opaque); - SaveStateHandler *save_state; -+ - int (*save_live_setup)(QEMUFile *f, void *opaque); -- int (*save_live_iterate)(QEMUFile *f, void *opaque); -+ void (*cancel)(void *opaque); - int (*save_live_complete)(QEMUFile *f, void *opaque); -+ bool (*is_active)(void *opaque); -+ int (*save_live_iterate)(QEMUFile *f, void *opaque); - uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size); -- void (*cancel)(void *opaque); -+ - LoadStateHandler *load_state; -- bool (*is_active)(void *opaque); - } SaveVMHandlers; - - int register_savevm(DeviceState *dev, diff --git a/0126-migration-run-pending-iterate-callbacks-out-of-big-l.patch b/0126-migration-run-pending-iterate-callbacks-out-of-big-l.patch deleted file mode 100644 index b9aea16..0000000 --- a/0126-migration-run-pending-iterate-callbacks-out-of-big-l.patch +++ /dev/null @@ -1,265 +0,0 @@ -From efb8ea48a730325b4bb4cfd1b624e697b1522536 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:27 +0100 -Subject: [PATCH] migration: run pending/iterate callbacks out of big lock - -This makes it possible to do blocking writes directly to the socket, -with no buffer in the middle. For RAM, only the migration_bitmap_sync() -call needs the iothread lock. For block migration, it is needed by -the block layer (including bdrv_drain_all and dirty bitmap access), -but because some code is shared between iterate and complete, all of -mig_save_device_dirty is run with the lock taken. - -In the savevm case, the iterate callback runs within the big lock. -This is annoying because it complicates the rules. Luckily we do not -need to do anything about it: the RAM iterate callback does not need -the iothread lock, and block migration never runs during savevm. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 32c835ba3984728c22d4e73cdb595090a60f437e) ---- - arch_init.c | 4 ++++ - block-migration.c | 37 +++++++++++++++++++++++++++++++++++-- - include/migration/vmstate.h | 11 +++++++++++ - migration.c | 4 ++-- - 4 files changed, 52 insertions(+), 4 deletions(-) - -diff --git a/arch_init.c b/arch_init.c -index 8daeafa..32b4378 100644 ---- a/arch_init.c -+++ b/arch_init.c -@@ -379,6 +379,8 @@ static inline bool migration_bitmap_set_dirty(MemoryRegion *mr, - return ret; - } - -+/* Needs iothread lock! */ -+ - static void migration_bitmap_sync(void) - { - RAMBlock *block; -@@ -690,7 +692,9 @@ static uint64_t ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) - remaining_size = ram_save_remaining() * TARGET_PAGE_SIZE; - - if (remaining_size < max_size) { -+ qemu_mutex_lock_iothread(); - migration_bitmap_sync(); -+ qemu_mutex_unlock_iothread(); - remaining_size = ram_save_remaining() * TARGET_PAGE_SIZE; - } - return remaining_size; -diff --git a/block-migration.c b/block-migration.c -index b726c6c..8da5f86 100644 ---- a/block-migration.c -+++ b/block-migration.c -@@ -107,6 +107,10 @@ static void blk_mig_unlock(void) - qemu_mutex_unlock(&block_mig_state.lock); - } - -+/* Must run outside of the iothread lock during the bulk phase, -+ * or the VM will stall. -+ */ -+ - static void blk_send(QEMUFile *f, BlkMigBlock * blk) - { - int len; -@@ -226,6 +230,8 @@ static void blk_mig_read_cb(void *opaque, int ret) - blk_mig_unlock(); - } - -+/* Called with no lock taken. */ -+ - static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - { - int64_t total_sectors = bmds->total_sectors; -@@ -235,11 +241,13 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - int nr_sectors; - - if (bmds->shared_base) { -+ qemu_mutex_lock_iothread(); - while (cur_sector < total_sectors && - !bdrv_is_allocated(bs, cur_sector, MAX_IS_ALLOCATED_SEARCH, - &nr_sectors)) { - cur_sector += nr_sectors; - } -+ qemu_mutex_unlock_iothread(); - } - - if (cur_sector >= total_sectors) { -@@ -272,15 +280,19 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) - block_mig_state.submitted++; - blk_mig_unlock(); - -+ qemu_mutex_lock_iothread(); - blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); - - bdrv_reset_dirty(bs, cur_sector, nr_sectors); -- bmds->cur_sector = cur_sector + nr_sectors; -+ qemu_mutex_unlock_iothread(); - -+ bmds->cur_sector = cur_sector + nr_sectors; - return (bmds->cur_sector >= total_sectors); - } - -+/* Called with iothread lock taken. */ -+ - static void set_dirty_tracking(int enable) - { - BlkMigDevState *bmds; -@@ -336,6 +348,8 @@ static void init_blk_migration(QEMUFile *f) - bdrv_iterate(init_blk_migration_it, NULL); - } - -+/* Called with no lock taken. */ -+ - static int blk_mig_save_bulked_block(QEMUFile *f) - { - int64_t completed_sector_sum = 0; -@@ -382,6 +396,8 @@ static void blk_mig_reset_dirty_cursor(void) - } - } - -+/* Called with iothread lock taken. */ -+ - static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, - int is_async) - { -@@ -451,7 +467,9 @@ error: - return ret; - } - --/* return value: -+/* Called with iothread lock taken. -+ * -+ * return value: - * 0: too much data for max_downtime - * 1: few enough data for max_downtime - */ -@@ -470,6 +488,8 @@ static int blk_mig_save_dirty_block(QEMUFile *f, int is_async) - return ret; - } - -+/* Called with no locks taken. */ -+ - static int flush_blks(QEMUFile *f) - { - BlkMigBlock *blk; -@@ -509,6 +529,8 @@ static int flush_blks(QEMUFile *f) - return ret; - } - -+/* Called with iothread lock taken. */ -+ - static int64_t get_remaining_dirty(void) - { - BlkMigDevState *bmds; -@@ -521,6 +543,8 @@ static int64_t get_remaining_dirty(void) - return dirty << BDRV_SECTOR_BITS; - } - -+/* Called with iothread lock taken. */ -+ - static void blk_mig_cleanup(void) - { - BlkMigDevState *bmds; -@@ -600,7 +624,12 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - } - ret = 0; - } else { -+ /* Always called with iothread lock taken for -+ * simplicity, block_save_complete also calls it. -+ */ -+ qemu_mutex_lock_iothread(); - ret = blk_mig_save_dirty_block(f, 1); -+ qemu_mutex_unlock_iothread(); - } - if (ret < 0) { - return ret; -@@ -622,6 +651,8 @@ static int block_save_iterate(QEMUFile *f, void *opaque) - return qemu_ftell(f) - last_ftell; - } - -+/* Called with iothread lock taken. */ -+ - static int block_save_complete(QEMUFile *f, void *opaque) - { - int ret; -@@ -665,6 +696,7 @@ static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) - /* Estimate pending number of bytes to send */ - uint64_t pending; - -+ qemu_mutex_lock_iothread(); - blk_mig_lock(); - pending = get_remaining_dirty() + - block_mig_state.submitted * BLOCK_SIZE + -@@ -675,6 +707,7 @@ static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) - pending = BLOCK_SIZE; - } - blk_mig_unlock(); -+ qemu_mutex_unlock_iothread(); - - DPRINTF("Enter save live pending %" PRIu64 "\n", pending); - return pending; -diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h -index 6229569..5f803f5 100644 ---- a/include/migration/vmstate.h -+++ b/include/migration/vmstate.h -@@ -30,14 +30,25 @@ typedef void SaveStateHandler(QEMUFile *f, void *opaque); - typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id); - - typedef struct SaveVMHandlers { -+ /* This runs inside the iothread lock. */ - void (*set_params)(const MigrationParams *params, void * opaque); - SaveStateHandler *save_state; - - int (*save_live_setup)(QEMUFile *f, void *opaque); - void (*cancel)(void *opaque); - int (*save_live_complete)(QEMUFile *f, void *opaque); -+ -+ /* This runs both outside and inside the iothread lock. */ - bool (*is_active)(void *opaque); -+ -+ /* This runs outside the iothread lock in the migration case, and -+ * within the lock in the savevm case. The callback had better only -+ * use data that is local to the migration thread or protected -+ * by other locks. -+ */ - int (*save_live_iterate)(QEMUFile *f, void *opaque); -+ -+ /* This runs outside the iothread lock! */ - uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size); - - LoadStateHandler *load_state; -diff --git a/migration.c b/migration.c -index 437475b..87b5009 100644 ---- a/migration.c -+++ b/migration.c -@@ -670,7 +670,6 @@ static void *buffered_file_thread(void *opaque) - uint64_t pending_size; - - if (s->bytes_xfer < s->xfer_limit) { -- qemu_mutex_lock_iothread(); - DPRINTF("iterate\n"); - pending_size = qemu_savevm_state_pending(s->file, max_size); - DPRINTF("pending size %lu max %lu\n", pending_size, max_size); -@@ -678,6 +677,7 @@ static void *buffered_file_thread(void *opaque) - qemu_savevm_state_iterate(s->file); - } else { - DPRINTF("done iterating\n"); -+ qemu_mutex_lock_iothread(); - start_time = qemu_get_clock_ms(rt_clock); - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); - old_vm_running = runstate_is_running(); -@@ -685,8 +685,8 @@ static void *buffered_file_thread(void *opaque) - s->xfer_limit = INT_MAX; - qemu_savevm_state_complete(s->file); - last_round = true; -+ qemu_mutex_unlock_iothread(); - } -- qemu_mutex_unlock_iothread(); - } - - current_time = qemu_get_clock_ms(rt_clock); diff --git a/0127-migration-run-setup-callbacks-out-of-big-lock.patch b/0127-migration-run-setup-callbacks-out-of-big-lock.patch deleted file mode 100644 index b4609fb..0000000 --- a/0127-migration-run-setup-callbacks-out-of-big-lock.patch +++ /dev/null @@ -1,117 +0,0 @@ -From ffe95e1c4daef0e563b8d70a8f456f9e7037818d Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:28 +0100 -Subject: [PATCH] migration: run setup callbacks out of big lock - -Only the migration_bitmap_sync() call needs the iothread lock. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 9b0950375277467fd74a9075624477ae43b9bb22) ---- - arch_init.c | 10 ++++++---- - block-migration.c | 2 ++ - include/migration/vmstate.h | 2 +- - migration.c | 2 -- - savevm.c | 3 +++ - 5 files changed, 12 insertions(+), 7 deletions(-) - -diff --git a/arch_init.c b/arch_init.c -index 32b4378..6089c53 100644 ---- a/arch_init.c -+++ b/arch_init.c -@@ -570,10 +570,6 @@ static int ram_save_setup(QEMUFile *f, void *opaque) - bitmap_set(migration_bitmap, 0, ram_pages); - migration_dirty_pages = ram_pages; - -- qemu_mutex_lock_ramlist(); -- bytes_transferred = 0; -- reset_ram_globals(); -- - if (migrate_use_xbzrle()) { - XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() / - TARGET_PAGE_SIZE, -@@ -587,8 +583,14 @@ static int ram_save_setup(QEMUFile *f, void *opaque) - acct_clear(); - } - -+ qemu_mutex_lock_iothread(); -+ qemu_mutex_lock_ramlist(); -+ bytes_transferred = 0; -+ reset_ram_globals(); -+ - memory_global_dirty_log_start(); - migration_bitmap_sync(); -+ qemu_mutex_unlock_iothread(); - - qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE); - -diff --git a/block-migration.c b/block-migration.c -index 8da5f86..2fd7699 100644 ---- a/block-migration.c -+++ b/block-migration.c -@@ -583,10 +583,12 @@ static int block_save_setup(QEMUFile *f, void *opaque) - DPRINTF("Enter save live setup submitted %d transferred %d\n", - block_mig_state.submitted, block_mig_state.transferred); - -+ qemu_mutex_lock_iothread(); - init_blk_migration(f); - - /* start track dirty blocks */ - set_dirty_tracking(1); -+ qemu_mutex_unlock_iothread(); - - ret = flush_blks(f); - blk_mig_reset_dirty_cursor(); -diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h -index 5f803f5..abc3b47 100644 ---- a/include/migration/vmstate.h -+++ b/include/migration/vmstate.h -@@ -34,7 +34,6 @@ typedef struct SaveVMHandlers { - void (*set_params)(const MigrationParams *params, void * opaque); - SaveStateHandler *save_state; - -- int (*save_live_setup)(QEMUFile *f, void *opaque); - void (*cancel)(void *opaque); - int (*save_live_complete)(QEMUFile *f, void *opaque); - -@@ -49,6 +48,7 @@ typedef struct SaveVMHandlers { - int (*save_live_iterate)(QEMUFile *f, void *opaque); - - /* This runs outside the iothread lock! */ -+ int (*save_live_setup)(QEMUFile *f, void *opaque); - uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size); - - LoadStateHandler *load_state; -diff --git a/migration.c b/migration.c -index 87b5009..7c1d4df 100644 ---- a/migration.c -+++ b/migration.c -@@ -660,10 +660,8 @@ static void *buffered_file_thread(void *opaque) - bool old_vm_running = false; - bool last_round = false; - -- qemu_mutex_lock_iothread(); - DPRINTF("beginning savevm\n"); - qemu_savevm_state_begin(s->file, &s->params); -- qemu_mutex_unlock_iothread(); - - while (s->state == MIG_STATE_ACTIVE) { - int64_t current_time; -diff --git a/savevm.c b/savevm.c -index e10a045..7c7774e 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -1768,7 +1768,10 @@ static int qemu_savevm_state(QEMUFile *f) - return -EINVAL; - } - -+ qemu_mutex_unlock_iothread(); - qemu_savevm_state_begin(f, ¶ms); -+ qemu_mutex_lock_iothread(); -+ - while (qemu_file_get_error(f) == 0) { - if (qemu_savevm_state_iterate(f) > 0) { - break; diff --git a/0128-migration-yay-buffering-is-gone.patch b/0128-migration-yay-buffering-is-gone.patch deleted file mode 100644 index 6d7a911..0000000 --- a/0128-migration-yay-buffering-is-gone.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 4354cf42b4976ffc12b930cae1a4e9d8f9f71f08 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:29 +0100 -Subject: [PATCH] migration: yay, buffering is gone - -Buffering was needed because blocking writes could take a long time -and starve other threads seeking to grab the big QEMU mutex. - -Now that all writes (except within _complete callbacks) are done -outside the big QEMU mutex, we do not need buffering at all. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit edaae611f6df0d66a8b5a90c84123b72980c7a22) ---- - include/migration/migration.h | 3 -- - migration.c | 79 ++++++++++++------------------------------- - savevm.c | 1 + - 3 files changed, 22 insertions(+), 61 deletions(-) - -diff --git a/include/migration/migration.h b/include/migration/migration.h -index ed20bed..cec8643 100644 ---- a/include/migration/migration.h -+++ b/include/migration/migration.h -@@ -34,9 +34,6 @@ struct MigrationState - int64_t bandwidth_limit; - size_t bytes_xfer; - size_t xfer_limit; -- uint8_t *buffer; -- size_t buffer_size; -- size_t buffer_capacity; - QemuThread thread; - QEMUBH *cleanup_bh; - -diff --git a/migration.c b/migration.c -index 7c1d4df..62a7f8e 100644 ---- a/migration.c -+++ b/migration.c -@@ -514,73 +514,41 @@ int64_t migrate_xbzrle_cache_size(void) - - /* migration thread support */ - -- --static void buffered_flush(MigrationState *s) --{ -- size_t offset = 0; -- ssize_t ret = 0; -- -- DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size); -- -- if (qemu_file_get_error(s->file)) { -- s->buffer_size = 0; -- return; -- } -- qemu_fflush(s->file); -- -- while (s->bytes_xfer < s->xfer_limit && offset < s->buffer_size) { -- size_t to_send = MIN(s->buffer_size - offset, s->xfer_limit - s->bytes_xfer); -- ret = migrate_fd_put_buffer(s, s->buffer + offset, to_send); -- if (ret <= 0) { -- DPRINTF("error flushing data, %zd\n", ret); -- break; -- } else { -- DPRINTF("flushed %zd byte(s)\n", ret); -- offset += ret; -- s->bytes_xfer += ret; -- } -- } -- -- DPRINTF("flushed %zu of %zu byte(s)\n", offset, s->buffer_size); -- memmove(s->buffer, s->buffer + offset, s->buffer_size - offset); -- s->buffer_size -= offset; -- -- if (ret < 0) { -- qemu_file_set_error(s->file, ret); -- } --} -- - static int buffered_put_buffer(void *opaque, const uint8_t *buf, - int64_t pos, int size) - { - MigrationState *s = opaque; -- ssize_t error; -+ ssize_t ret; -+ size_t sent; - - DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); - -- error = qemu_file_get_error(s->file); -- if (error) { -- DPRINTF("flush when error, bailing: %s\n", strerror(-error)); -- return error; -+ ret = qemu_file_get_error(s->file); -+ if (ret) { -+ DPRINTF("flush when error, bailing: %s\n", strerror(-ret)); -+ return ret; - } - - if (size <= 0) { - return size; - } - -- if (size > (s->buffer_capacity - s->buffer_size)) { -- DPRINTF("increasing buffer capacity from %zu by %zu\n", -- s->buffer_capacity, size + 1024); -- -- s->buffer_capacity += size + 1024; -- -- s->buffer = g_realloc(s->buffer, s->buffer_capacity); -+ sent = 0; -+ while (size) { -+ ret = migrate_fd_put_buffer(s, buf, size); -+ if (ret <= 0) { -+ DPRINTF("error flushing data, %zd\n", ret); -+ return ret; -+ } else { -+ DPRINTF("flushed %zd byte(s)\n", ret); -+ sent += ret; -+ buf += ret; -+ size -= ret; -+ s->bytes_xfer += ret; -+ } - } - -- memcpy(s->buffer + s->buffer_size, buf, size); -- s->buffer_size += size; -- -- return size; -+ return sent; - } - - static int buffered_close(void *opaque) -@@ -712,10 +680,9 @@ static void *buffered_file_thread(void *opaque) - g_usleep((initial_time + BUFFER_DELAY - current_time)*1000); - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } -- buffered_flush(s); - if (qemu_file_get_error(s->file)) { - migrate_finish_set_state(s, MIG_STATE_ERROR); -- } else if (last_round && s->buffer_size == 0) { -+ } else if (last_round) { - migrate_finish_set_state(s, MIG_STATE_COMPLETED); - } - } -@@ -735,7 +702,6 @@ static void *buffered_file_thread(void *opaque) - qemu_bh_schedule(s->cleanup_bh); - qemu_mutex_unlock_iothread(); - -- g_free(s->buffer); - return NULL; - } - -@@ -754,9 +720,6 @@ void migrate_fd_connect(MigrationState *s) - trace_migrate_set_state(MIG_STATE_ACTIVE); - - s->bytes_xfer = 0; -- s->buffer = NULL; -- s->buffer_size = 0; -- s->buffer_capacity = 0; - /* This is a best 1st approximation. ns to ms */ - s->expected_downtime = max_downtime/1000000; - -diff --git a/savevm.c b/savevm.c -index 7c7774e..ce10295 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -1724,6 +1724,7 @@ void qemu_savevm_state_complete(QEMUFile *f) - } - - qemu_put_byte(f, QEMU_VM_EOF); -+ qemu_fflush(f); - } - - uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size) diff --git a/0129-Rename-buffered_-to-migration_.patch b/0129-Rename-buffered_-to-migration_.patch deleted file mode 100644 index b9484f6..0000000 --- a/0129-Rename-buffered_-to-migration_.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 1b49e3073fada9243cb16e24aaa09e19a6675881 Mon Sep 17 00:00:00 2001 -From: Juan Quintela -Date: Fri, 22 Feb 2013 17:36:30 +0100 -Subject: [PATCH] Rename buffered_ to migration_ - -This is consistent once that we have moved everything to migration.c - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -(cherry picked from commit 5f496a1be3d15f192be1ab1fed3a3278fd5a91a1) ---- - migration.c | 32 ++++++++++++++++---------------- - 1 file changed, 16 insertions(+), 16 deletions(-) - -diff --git a/migration.c b/migration.c -index 62a7f8e..71c6c10 100644 ---- a/migration.c -+++ b/migration.c -@@ -514,7 +514,7 @@ int64_t migrate_xbzrle_cache_size(void) - - /* migration thread support */ - --static int buffered_put_buffer(void *opaque, const uint8_t *buf, -+static int migration_put_buffer(void *opaque, const uint8_t *buf, - int64_t pos, int size) - { - MigrationState *s = opaque; -@@ -551,7 +551,7 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, - return sent; - } - --static int buffered_close(void *opaque) -+static int migration_close(void *opaque) - { - MigrationState *s = opaque; - -@@ -565,7 +565,7 @@ static int buffered_close(void *opaque) - return migrate_fd_close(s); - } - --static int buffered_get_fd(void *opaque) -+static int migration_get_fd(void *opaque) - { - MigrationState *s = opaque; - -@@ -578,7 +578,7 @@ static int buffered_get_fd(void *opaque) - * 1: Time to stop - * negative: There has been an error - */ --static int buffered_rate_limit(void *opaque) -+static int migration_rate_limit(void *opaque) - { - MigrationState *s = opaque; - int ret; -@@ -595,7 +595,7 @@ static int buffered_rate_limit(void *opaque) - return 0; - } - --static int64_t buffered_set_rate_limit(void *opaque, int64_t new_rate) -+static int64_t migration_set_rate_limit(void *opaque, int64_t new_rate) - { - MigrationState *s = opaque; - if (qemu_file_get_error(s->file)) { -@@ -611,14 +611,14 @@ out: - return s->xfer_limit; - } - --static int64_t buffered_get_rate_limit(void *opaque) -+static int64_t migration_get_rate_limit(void *opaque) - { - MigrationState *s = opaque; - - return s->xfer_limit; - } - --static void *buffered_file_thread(void *opaque) -+static void *migration_thread(void *opaque) - { - MigrationState *s = opaque; - int64_t initial_time = qemu_get_clock_ms(rt_clock); -@@ -705,13 +705,13 @@ static void *buffered_file_thread(void *opaque) - return NULL; - } - --static const QEMUFileOps buffered_file_ops = { -- .get_fd = buffered_get_fd, -- .put_buffer = buffered_put_buffer, -- .close = buffered_close, -- .rate_limit = buffered_rate_limit, -- .get_rate_limit = buffered_get_rate_limit, -- .set_rate_limit = buffered_set_rate_limit, -+static const QEMUFileOps migration_file_ops = { -+ .get_fd = migration_get_fd, -+ .put_buffer = migration_put_buffer, -+ .close = migration_close, -+ .rate_limit = migration_rate_limit, -+ .get_rate_limit = migration_get_rate_limit, -+ .set_rate_limit = migration_set_rate_limit, - }; - - void migrate_fd_connect(MigrationState *s) -@@ -726,9 +726,9 @@ void migrate_fd_connect(MigrationState *s) - s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; - - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); -- s->file = qemu_fopen_ops(s, &buffered_file_ops); -+ s->file = qemu_fopen_ops(s, &migration_file_ops); - -- qemu_thread_create(&s->thread, buffered_file_thread, s, -+ qemu_thread_create(&s->thread, migration_thread, s, - QEMU_THREAD_JOINABLE); - notifier_list_notify(&migration_state_notifiers, s); - } diff --git a/0130-qemu-file-make-qemu_fflush-and-qemu_file_set_error-p.patch b/0130-qemu-file-make-qemu_fflush-and-qemu_file_set_error-p.patch deleted file mode 100644 index 434ef9f..0000000 --- a/0130-qemu-file-make-qemu_fflush-and-qemu_file_set_error-p.patch +++ /dev/null @@ -1,58 +0,0 @@ -From d1e45898016eb902411abe5c5b377a490e2b03b2 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:31 +0100 -Subject: [PATCH] qemu-file: make qemu_fflush and qemu_file_set_error private - again - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 05f28b837c6bd6124abab2496ce15c07a334a5ad) ---- - include/migration/qemu-file.h | 2 -- - savevm.c | 4 ++-- - 2 files changed, 2 insertions(+), 4 deletions(-) - -diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h -index 5e0c287..46fc11d 100644 ---- a/include/migration/qemu-file.h -+++ b/include/migration/qemu-file.h -@@ -82,7 +82,6 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode); - int qemu_get_fd(QEMUFile *f); - int qemu_fclose(QEMUFile *f); - int64_t qemu_ftell(QEMUFile *f); --void qemu_fflush(QEMUFile *f); - void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); - void qemu_put_byte(QEMUFile *f, int v); - -@@ -114,7 +113,6 @@ int qemu_file_rate_limit(QEMUFile *f); - int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); - int64_t qemu_file_get_rate_limit(QEMUFile *f); - int qemu_file_get_error(QEMUFile *f); --void qemu_file_set_error(QEMUFile *f, int ret); - - static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv) - { -diff --git a/savevm.c b/savevm.c -index ce10295..fef2ab9 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -443,7 +443,7 @@ int qemu_file_get_error(QEMUFile *f) - return f->last_error; - } - --void qemu_file_set_error(QEMUFile *f, int ret) -+static void qemu_file_set_error(QEMUFile *f, int ret) - { - if (f->last_error == 0) { - f->last_error = ret; -@@ -453,7 +453,7 @@ void qemu_file_set_error(QEMUFile *f, int ret) - /** Flushes QEMUFile buffer - * - */ --void qemu_fflush(QEMUFile *f) -+static void qemu_fflush(QEMUFile *f) - { - int ret = 0; - diff --git a/0131-migration-eliminate-last_round.patch b/0131-migration-eliminate-last_round.patch deleted file mode 100644 index 8feb887..0000000 --- a/0131-migration-eliminate-last_round.patch +++ /dev/null @@ -1,67 +0,0 @@ -From cc3b3656b4fcca8dcdfe6d174615333d7486ce69 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:32 +0100 -Subject: [PATCH] migration: eliminate last_round - -We will go around the loop exactly once after setting last_round. -Eliminate the variable altogether. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 059f896cefb2776181e39d9ba69345bd9d07d52b) ---- - migration.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/migration.c b/migration.c -index 71c6c10..a888f36 100644 ---- a/migration.c -+++ b/migration.c -@@ -626,7 +626,6 @@ static void *migration_thread(void *opaque) - int64_t max_size = 0; - int64_t start_time = initial_time; - bool old_vm_running = false; -- bool last_round = false; - - DPRINTF("beginning savevm\n"); - qemu_savevm_state_begin(s->file, &s->params); -@@ -650,8 +649,11 @@ static void *migration_thread(void *opaque) - vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); - s->xfer_limit = INT_MAX; - qemu_savevm_state_complete(s->file); -- last_round = true; - qemu_mutex_unlock_iothread(); -+ if (!qemu_file_get_error(s->file)) { -+ migrate_finish_set_state(s, MIG_STATE_COMPLETED); -+ break; -+ } - } - } - -@@ -675,15 +677,13 @@ static void *migration_thread(void *opaque) - sleep_time = 0; - initial_time = current_time; - } -- if (!last_round && (s->bytes_xfer >= s->xfer_limit)) { -+ if (s->bytes_xfer >= s->xfer_limit) { - /* usleep expects microseconds */ - g_usleep((initial_time + BUFFER_DELAY - current_time)*1000); - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } - if (qemu_file_get_error(s->file)) { - migrate_finish_set_state(s, MIG_STATE_ERROR); -- } else if (last_round) { -- migrate_finish_set_state(s, MIG_STATE_COMPLETED); - } - } - -@@ -695,7 +695,6 @@ static void *migration_thread(void *opaque) - runstate_set(RUN_STATE_POSTMIGRATE); - } else { - if (old_vm_running) { -- assert(last_round); - vm_start(); - } - } diff --git a/0132-migration-detect-error-before-sleeping.patch b/0132-migration-detect-error-before-sleeping.patch deleted file mode 100644 index 2bad0a2..0000000 --- a/0132-migration-detect-error-before-sleeping.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 409d6af88505169acec3bf3ae005eba79a981688 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:33 +0100 -Subject: [PATCH] migration: detect error before sleeping - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit fd45ee2c643bb3d55de5c54b50c23859ca631a9f) ---- - migration.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/migration.c b/migration.c -index a888f36..35c3455 100644 ---- a/migration.c -+++ b/migration.c -@@ -657,6 +657,10 @@ static void *migration_thread(void *opaque) - } - } - -+ if (qemu_file_get_error(s->file)) { -+ migrate_finish_set_state(s, MIG_STATE_ERROR); -+ break; -+ } - current_time = qemu_get_clock_ms(rt_clock); - if (current_time >= initial_time + BUFFER_DELAY) { - uint64_t transferred_bytes = s->bytes_xfer; -@@ -682,9 +686,6 @@ static void *migration_thread(void *opaque) - g_usleep((initial_time + BUFFER_DELAY - current_time)*1000); - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } -- if (qemu_file_get_error(s->file)) { -- migrate_finish_set_state(s, MIG_STATE_ERROR); -- } - } - - qemu_mutex_lock_iothread(); diff --git a/0133-migration-remove-useless-qemu_file_get_error-check.patch b/0133-migration-remove-useless-qemu_file_get_error-check.patch deleted file mode 100644 index 993ffc1..0000000 --- a/0133-migration-remove-useless-qemu_file_get_error-check.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8469b1f717180ae0ca4e764afcbaa61c931ab8d4 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:34 +0100 -Subject: [PATCH] migration: remove useless qemu_file_get_error check - -migration_put_buffer is never called if there has been an error. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit db2f25309af1af0f27e0ddec4acc3b66837fa668) ---- - migration.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/migration.c b/migration.c -index 35c3455..d75beca 100644 ---- a/migration.c -+++ b/migration.c -@@ -523,12 +523,6 @@ static int migration_put_buffer(void *opaque, const uint8_t *buf, - - DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); - -- ret = qemu_file_get_error(s->file); -- if (ret) { -- DPRINTF("flush when error, bailing: %s\n", strerror(-ret)); -- return ret; -- } -- - if (size <= 0) { - return size; - } diff --git a/0134-migration-use-qemu_file_rate_limit-consistently.patch b/0134-migration-use-qemu_file_rate_limit-consistently.patch deleted file mode 100644 index 855cdb5..0000000 --- a/0134-migration-use-qemu_file_rate_limit-consistently.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 59df9d30f0f54158975a3d3642a1d655b177cdfe Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:35 +0100 -Subject: [PATCH] migration: use qemu_file_rate_limit consistently - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit a0ff044b8ea81908cd8fe5819ce33780f53f58ee) ---- - migration.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/migration.c b/migration.c -index d75beca..ae2c83c 100644 ---- a/migration.c -+++ b/migration.c -@@ -628,7 +628,7 @@ static void *migration_thread(void *opaque) - int64_t current_time; - uint64_t pending_size; - -- if (s->bytes_xfer < s->xfer_limit) { -+ if (!qemu_file_rate_limit(s->file)) { - DPRINTF("iterate\n"); - pending_size = qemu_savevm_state_pending(s->file, max_size); - DPRINTF("pending size %lu max %lu\n", pending_size, max_size); -@@ -675,7 +675,7 @@ static void *migration_thread(void *opaque) - sleep_time = 0; - initial_time = current_time; - } -- if (s->bytes_xfer >= s->xfer_limit) { -+ if (qemu_file_rate_limit(s->file)) { - /* usleep expects microseconds */ - g_usleep((initial_time + BUFFER_DELAY - current_time)*1000); - sleep_time += qemu_get_clock_ms(rt_clock) - current_time; diff --git a/0135-migration-merge-qemu_popen_cmd-with-qemu_popen.patch b/0135-migration-merge-qemu_popen_cmd-with-qemu_popen.patch deleted file mode 100644 index 99c446f..0000000 --- a/0135-migration-merge-qemu_popen_cmd-with-qemu_popen.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 4f88dd44aa288f1ded954850a9a222f4ecdf00b8 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:36 +0100 -Subject: [PATCH] migration: merge qemu_popen_cmd with qemu_popen - -There is no reason for outgoing exec migration to do popen manually -anymore (the reason used to be that we needed the FILE* to make it -non-blocking). Use qemu_popen_cmd. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 817b9ed5eb300dbb434d752da416441028539a96) ---- - include/migration/qemu-file.h | 1 - - migration-exec.c | 10 ++++------ - savevm.c | 22 ++++++++-------------- - 3 files changed, 12 insertions(+), 21 deletions(-) - -diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h -index 46fc11d..987e719 100644 ---- a/include/migration/qemu-file.h -+++ b/include/migration/qemu-file.h -@@ -77,7 +77,6 @@ QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops); - QEMUFile *qemu_fopen(const char *filename, const char *mode); - QEMUFile *qemu_fdopen(int fd, const char *mode); - QEMUFile *qemu_fopen_socket(int fd); --QEMUFile *qemu_popen(FILE *popen_file, const char *mode); - QEMUFile *qemu_popen_cmd(const char *command, const char *mode); - int qemu_get_fd(QEMUFile *f); - int qemu_fclose(QEMUFile *f); -diff --git a/migration-exec.c b/migration-exec.c -index a051a6e..5dc7313 100644 ---- a/migration-exec.c -+++ b/migration-exec.c -@@ -59,19 +59,17 @@ static int exec_close(MigrationState *s) - - void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp) - { -- FILE *f; -- -- f = popen(command, "w"); -+ QEMUFile *f; -+ f = qemu_popen_cmd(command, "w"); - if (f == NULL) { - error_setg_errno(errp, errno, "failed to popen the migration target"); - return; - } - -- s->fd = fileno(f); -+ s->opaque = f; -+ s->fd = qemu_get_fd(f); - assert(s->fd != -1); - -- s->opaque = qemu_popen(f, "w"); -- - s->close = exec_close; - s->get_error = file_errno; - s->write = file_write; -diff --git a/savevm.c b/savevm.c -index fef2ab9..38699de 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -275,11 +275,17 @@ static const QEMUFileOps stdio_pipe_write_ops = { - .close = stdio_pclose - }; - --QEMUFile *qemu_popen(FILE *stdio_file, const char *mode) -+QEMUFile *qemu_popen_cmd(const char *command, const char *mode) - { -+ FILE *stdio_file; - QEMUFileStdio *s; - -- if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) { -+ stdio_file = popen(command, mode); -+ if (stdio_file == NULL) { -+ return NULL; -+ } -+ -+ if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) { - fprintf(stderr, "qemu_popen: Argument validity check failed\n"); - return NULL; - } -@@ -296,18 +302,6 @@ QEMUFile *qemu_popen(FILE *stdio_file, const char *mode) - return s->file; - } - --QEMUFile *qemu_popen_cmd(const char *command, const char *mode) --{ -- FILE *popen_file; -- -- popen_file = popen(command, mode); -- if(popen_file == NULL) { -- return NULL; -- } -- -- return qemu_popen(popen_file, mode); --} -- - static const QEMUFileOps stdio_file_read_ops = { - .get_fd = stdio_get_fd, - .get_buffer = stdio_get_buffer, diff --git a/0136-qemu-file-fsync-a-writable-stdio-QEMUFile.patch b/0136-qemu-file-fsync-a-writable-stdio-QEMUFile.patch deleted file mode 100644 index d3d677e..0000000 --- a/0136-qemu-file-fsync-a-writable-stdio-QEMUFile.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 701731a81e40d7321f619020b9062a5d88f7466a Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:37 +0100 -Subject: [PATCH] qemu-file: fsync a writable stdio QEMUFile - -This is what fd_close does. Prepare for switching to a QEMUFile. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit ce39ee3184a02eca7f9529cc19b1582f6f704c70) ---- - savevm.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/savevm.c b/savevm.c -index 38699de..1d49fde 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -256,6 +256,24 @@ static int stdio_fclose(void *opaque) - { - QEMUFileStdio *s = opaque; - int ret = 0; -+ -+ if (s->file->ops->put_buffer) { -+ int fd = fileno(s->stdio_file); -+ struct stat st; -+ -+ ret = fstat(fd, &st); -+ if (ret == 0 && S_ISREG(st.st_mode)) { -+ /* -+ * If the file handle is a regular file make sure the -+ * data is flushed to disk before signaling success. -+ */ -+ ret = fsync(fd); -+ if (ret != 0) { -+ ret = -errno; -+ return ret; -+ } -+ } -+ } - if (fclose(s->stdio_file) == EOF) { - ret = -errno; - } diff --git a/0137-qemu-file-check-exit-status-when-closing-a-pipe-QEMU.patch b/0137-qemu-file-check-exit-status-when-closing-a-pipe-QEMU.patch deleted file mode 100644 index 3b09581..0000000 --- a/0137-qemu-file-check-exit-status-when-closing-a-pipe-QEMU.patch +++ /dev/null @@ -1,65 +0,0 @@ -From ba58f61422bff38da15331a092adfd2cfaadc8d5 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:38 +0100 -Subject: [PATCH] qemu-file: check exit status when closing a pipe QEMUFile - -This is what exec_close does. Move this to the underlying QEMUFile. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 13c7b2da073ec83cb47f9582149c8d28bb038e73) ---- - include/qemu/osdep.h | 7 +++++++ - migration-exec.c | 4 ---- - savevm.c | 3 +++ - 3 files changed, 10 insertions(+), 4 deletions(-) - -diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h -index 87d3b9c..df24400 100644 ---- a/include/qemu/osdep.h -+++ b/include/qemu/osdep.h -@@ -9,6 +9,13 @@ - #include - #endif - -+#ifndef _WIN32 -+#include -+#else -+#define WIFEXITED(x) 1 -+#define WEXITSTATUS(x) (x) -+#endif -+ - #include - - #if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10 -diff --git a/migration-exec.c b/migration-exec.c -index 5dc7313..a2b5f8d 100644 ---- a/migration-exec.c -+++ b/migration-exec.c -@@ -50,10 +50,6 @@ static int exec_close(MigrationState *s) - ret = qemu_fclose(s->opaque); - s->opaque = NULL; - s->fd = -1; -- if (ret >= 0 && !(WIFEXITED(ret) && WEXITSTATUS(ret) == 0)) { -- /* close succeeded, but non-zero exit code: */ -- ret = -EIO; /* fake errno value */ -- } - return ret; - } - -diff --git a/savevm.c b/savevm.c -index 1d49fde..6d6f1f1 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -247,6 +247,9 @@ static int stdio_pclose(void *opaque) - ret = pclose(s->stdio_file); - if (ret == -1) { - ret = -errno; -+ } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { -+ /* close succeeded, but non-zero exit code: */ -+ ret = -EIO; /* fake errno value */ - } - g_free(s); - return ret; diff --git a/0138-qemu-file-add-writable-socket-QEMUFile.patch b/0138-qemu-file-add-writable-socket-QEMUFile.patch deleted file mode 100644 index aabd1e6..0000000 --- a/0138-qemu-file-add-writable-socket-QEMUFile.patch +++ /dev/null @@ -1,111 +0,0 @@ -From b38aa57a296bd4fdc31a9ebf3f28ffb612ad6e32 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:39 +0100 -Subject: [PATCH] qemu-file: add writable socket QEMUFile - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 0cc3f3ccc9d29acc94b995430518bda1c7c01bef) ---- - include/migration/qemu-file.h | 2 +- - migration-tcp.c | 2 +- - migration-unix.c | 2 +- - savevm.c | 33 +++++++++++++++++++++++++++++++-- - 4 files changed, 34 insertions(+), 5 deletions(-) - -diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h -index 987e719..25e8461 100644 ---- a/include/migration/qemu-file.h -+++ b/include/migration/qemu-file.h -@@ -76,7 +76,7 @@ typedef struct QEMUFileOps { - QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops); - QEMUFile *qemu_fopen(const char *filename, const char *mode); - QEMUFile *qemu_fdopen(int fd, const char *mode); --QEMUFile *qemu_fopen_socket(int fd); -+QEMUFile *qemu_fopen_socket(int fd, const char *mode); - QEMUFile *qemu_popen_cmd(const char *command, const char *mode); - int qemu_get_fd(QEMUFile *f); - int qemu_fclose(QEMUFile *f); -diff --git a/migration-tcp.c b/migration-tcp.c -index 59e3b7e..a748195 100644 ---- a/migration-tcp.c -+++ b/migration-tcp.c -@@ -95,7 +95,7 @@ static void tcp_accept_incoming_migration(void *opaque) - goto out; - } - -- f = qemu_fopen_socket(c); -+ f = qemu_fopen_socket(c, "rb"); - if (f == NULL) { - fprintf(stderr, "could not qemu_fopen socket\n"); - goto out; -diff --git a/migration-unix.c b/migration-unix.c -index 0ca2a21..d078f43 100644 ---- a/migration-unix.c -+++ b/migration-unix.c -@@ -95,7 +95,7 @@ static void unix_accept_incoming_migration(void *opaque) - goto out; - } - -- f = qemu_fopen_socket(c); -+ f = qemu_fopen_socket(c, "rb"); - if (f == NULL) { - fprintf(stderr, "could not qemu_fopen socket\n"); - goto out; -diff --git a/savevm.c b/savevm.c -index 6d6f1f1..76c88c7 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -198,6 +198,18 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) - return len; - } - -+static int socket_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size) -+{ -+ QEMUFileSocket *s = opaque; -+ ssize_t len; -+ -+ len = qemu_send_full(s->fd, buf, size, 0); -+ if (len < size) { -+ len = -socket_error(); -+ } -+ return len; -+} -+ - static int socket_close(void *opaque) - { - QEMUFileSocket *s = opaque; -@@ -369,12 +381,29 @@ static const QEMUFileOps socket_read_ops = { - .close = socket_close - }; - --QEMUFile *qemu_fopen_socket(int fd) -+static const QEMUFileOps socket_write_ops = { -+ .get_fd = socket_get_fd, -+ .put_buffer = socket_put_buffer, -+ .close = socket_close -+}; -+ -+QEMUFile *qemu_fopen_socket(int fd, const char *mode) - { - QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket)); - -+ if (mode == NULL || -+ (mode[0] != 'r' && mode[0] != 'w') || -+ mode[1] != 'b' || mode[2] != 0) { -+ fprintf(stderr, "qemu_fopen: Argument validity check failed\n"); -+ return NULL; -+ } -+ - s->fd = fd; -- s->file = qemu_fopen_ops(s, &socket_read_ops); -+ if (mode[0] == 'w') { -+ s->file = qemu_fopen_ops(s, &socket_write_ops); -+ } else { -+ s->file = qemu_fopen_ops(s, &socket_read_ops); -+ } - return s->file; - } - diff --git a/0139-qemu-file-simplify-and-export-qemu_ftell.patch b/0139-qemu-file-simplify-and-export-qemu_ftell.patch deleted file mode 100644 index b4c91ab..0000000 --- a/0139-qemu-file-simplify-and-export-qemu_ftell.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 6afaa318d59f4532dd9a6682704bfbfef280c86e Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:40 +0100 -Subject: [PATCH] qemu-file: simplify and export qemu_ftell - -Force a flush when qemu_ftell is called. This simplifies the buffer magic -(it also breaks qemu_ftell for input QEMUFiles, but we never use it). - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 3f2d38faab97f4d676c41868a8243997b2aab7cb) ---- - savevm.c | 20 ++++++++------------ - 1 file changed, 8 insertions(+), 12 deletions(-) - -diff --git a/savevm.c b/savevm.c -index 76c88c7..c60ace3 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -119,8 +119,8 @@ struct QEMUFile { - void *opaque; - int is_write; - -- int64_t buf_offset; /* start of buffer when writing, end of buffer -- when reading */ -+ int64_t pos; /* start of buffer when writing, end of buffer -+ when reading */ - int buf_index; - int buf_size; /* 0 when writing */ - uint8_t buf[IO_BUF_SIZE]; -@@ -505,9 +505,9 @@ static void qemu_fflush(QEMUFile *f) - return; - } - if (f->is_write && f->buf_index > 0) { -- ret = f->ops->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index); -+ ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index); - if (ret >= 0) { -- f->buf_offset += f->buf_index; -+ f->pos += f->buf_index; - } - f->buf_index = 0; - } -@@ -534,11 +534,11 @@ static void qemu_fill_buffer(QEMUFile *f) - f->buf_index = 0; - f->buf_size = pending; - -- len = f->ops->get_buffer(f->opaque, f->buf + pending, f->buf_offset, -+ len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos, - IO_BUF_SIZE - pending); - if (len > 0) { - f->buf_size += len; -- f->buf_offset += len; -+ f->pos += len; - } else if (len == 0) { - qemu_file_set_error(f, -EIO); - } else if (len != -EAGAIN) -@@ -718,12 +718,8 @@ int qemu_get_byte(QEMUFile *f) - - int64_t qemu_ftell(QEMUFile *f) - { -- /* buf_offset excludes buffer for writing but includes it for reading */ -- if (f->is_write) { -- return f->buf_offset + f->buf_index; -- } else { -- return f->buf_offset - f->buf_size + f->buf_index; -- } -+ qemu_fflush(f); -+ return f->pos; - } - - int qemu_file_rate_limit(QEMUFile *f) diff --git a/0140-migration-use-QEMUFile-for-migration-channel-lifetim.patch b/0140-migration-use-QEMUFile-for-migration-channel-lifetim.patch deleted file mode 100644 index 8754310..0000000 --- a/0140-migration-use-QEMUFile-for-migration-channel-lifetim.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 163a01830d0dbdb57f332915ebe298f86be84cb0 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:41 +0100 -Subject: [PATCH] migration: use QEMUFile for migration channel lifetime - -As a start, use QEMUFile to store the destination and close it. -qemu_get_fd gets a file descriptor that will be used by the write -callbacks. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit f8bbc1286337a8506162b5785babe6f2a7de2476) - -Conflicts: - migration-tcp.c - migration-unix.c - savevm.c ---- - include/migration/migration.h | 7 ++++--- - migration-exec.c | 21 ++------------------- - migration-fd.c | 35 +++-------------------------------- - migration-tcp.c | 19 +++---------------- - migration-unix.c | 19 +++---------------- - migration.c | 8 +++++--- - savevm.c | 1 + - 7 files changed, 21 insertions(+), 89 deletions(-) - -diff --git a/include/migration/migration.h b/include/migration/migration.h -index cec8643..1f8f305 100644 ---- a/include/migration/migration.h -+++ b/include/migration/migration.h -@@ -38,12 +38,13 @@ struct MigrationState - QEMUBH *cleanup_bh; - - QEMUFile *file; -+ QEMUFile *migration_file; -+ - int fd; -- int state; - int (*get_error)(MigrationState *s); -- int (*close)(MigrationState *s); - int (*write)(MigrationState *s, const void *buff, size_t size); -- void *opaque; -+ -+ int state; - MigrationParams params; - int64_t total_time; - int64_t downtime; -diff --git a/migration-exec.c b/migration-exec.c -index a2b5f8d..8c3f720 100644 ---- a/migration-exec.c -+++ b/migration-exec.c -@@ -43,33 +43,16 @@ static int file_write(MigrationState *s, const void * buf, size_t size) - return write(s->fd, buf, size); - } - --static int exec_close(MigrationState *s) --{ -- int ret = 0; -- DPRINTF("exec_close\n"); -- ret = qemu_fclose(s->opaque); -- s->opaque = NULL; -- s->fd = -1; -- return ret; --} -- - void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp) - { -- QEMUFile *f; -- f = qemu_popen_cmd(command, "w"); -- if (f == NULL) { -+ s->migration_file = qemu_popen_cmd(command, "w"); -+ if (s->migration_file == NULL) { - error_setg_errno(errp, errno, "failed to popen the migration target"); - return; - } - -- s->opaque = f; -- s->fd = qemu_get_fd(f); -- assert(s->fd != -1); -- -- s->close = exec_close; - s->get_error = file_errno; - s->write = file_write; -- - migrate_fd_connect(s); - } - -diff --git a/migration-fd.c b/migration-fd.c -index a99e0e3..4636457 100644 ---- a/migration-fd.c -+++ b/migration-fd.c -@@ -40,45 +40,16 @@ static int fd_write(MigrationState *s, const void * buf, size_t size) - return write(s->fd, buf, size); - } - --static int fd_close(MigrationState *s) --{ -- struct stat st; -- int ret; -- -- DPRINTF("fd_close\n"); -- ret = fstat(s->fd, &st); -- if (ret == 0 && S_ISREG(st.st_mode)) { -- /* -- * If the file handle is a regular file make sure the -- * data is flushed to disk before signaling success. -- */ -- ret = fsync(s->fd); -- if (ret != 0) { -- ret = -errno; -- perror("migration-fd: fsync"); -- return ret; -- } -- } -- ret = close(s->fd); -- s->fd = -1; -- if (ret != 0) { -- ret = -errno; -- perror("migration-fd: close"); -- } -- return ret; --} -- - void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) - { -- s->fd = monitor_get_fd(cur_mon, fdname, errp); -- if (s->fd == -1) { -+ int fd = monitor_get_fd(cur_mon, fdname, errp); -+ if (fd == -1) { - return; - } -+ s->migration_file = qemu_fdopen(fd, "wb"); - - s->get_error = fd_errno; - s->write = fd_write; -- s->close = fd_close; -- - migrate_fd_connect(s); - } - -diff --git a/migration-tcp.c b/migration-tcp.c -index a748195..1e8e004 100644 ---- a/migration-tcp.c -+++ b/migration-tcp.c -@@ -39,28 +39,17 @@ static int socket_write(MigrationState *s, const void * buf, size_t size) - return send(s->fd, buf, size, 0); - } - --static int tcp_close(MigrationState *s) --{ -- int r = 0; -- DPRINTF("tcp_close\n"); -- if (closesocket(s->fd) < 0) { -- r = -socket_error(); -- } -- return r; --} -- - static void tcp_wait_for_connect(int fd, void *opaque) - { - MigrationState *s = opaque; - - if (fd < 0) { - DPRINTF("migrate connect error\n"); -- s->fd = -1; -+ s->migration_file = NULL; - migrate_fd_error(s); - } else { - DPRINTF("migrate connect success\n"); -- s->fd = fd; -- qemu_set_block(s->fd); -+ s->migration_file = qemu_fopen_socket(fd, "wb"); - migrate_fd_connect(s); - } - } -@@ -69,9 +58,7 @@ void tcp_start_outgoing_migration(MigrationState *s, const char *host_port, Erro - { - s->get_error = socket_errno; - s->write = socket_write; -- s->close = tcp_close; -- -- s->fd = inet_nonblocking_connect(host_port, tcp_wait_for_connect, s, errp); -+ inet_nonblocking_connect(host_port, tcp_wait_for_connect, s, errp); - } - - static void tcp_accept_incoming_migration(void *opaque) -diff --git a/migration-unix.c b/migration-unix.c -index d078f43..11917f4 100644 ---- a/migration-unix.c -+++ b/migration-unix.c -@@ -39,28 +39,17 @@ static int unix_write(MigrationState *s, const void * buf, size_t size) - return write(s->fd, buf, size); - } - --static int unix_close(MigrationState *s) --{ -- int r = 0; -- DPRINTF("unix_close\n"); -- if (close(s->fd) < 0) { -- r = -errno; -- } -- return r; --} -- - static void unix_wait_for_connect(int fd, void *opaque) - { - MigrationState *s = opaque; - - if (fd < 0) { - DPRINTF("migrate connect error\n"); -- s->fd = -1; -+ s->migration_file = NULL; - migrate_fd_error(s); - } else { - DPRINTF("migrate connect success\n"); -- s->fd = fd; -- qemu_set_block(s->fd); -+ s->migration_file = qemu_fopen_socket(fd, "wb"); - migrate_fd_connect(s); - } - } -@@ -69,9 +58,7 @@ void unix_start_outgoing_migration(MigrationState *s, const char *path, Error ** - { - s->get_error = unix_errno; - s->write = unix_write; -- s->close = unix_close; -- -- s->fd = unix_nonblocking_connect(path, unix_wait_for_connect, s, errp); -+ unix_nonblocking_connect(path, unix_wait_for_connect, s, errp); - } - - static void unix_accept_incoming_migration(void *opaque) -diff --git a/migration.c b/migration.c -index ae2c83c..fa630ed 100644 ---- a/migration.c -+++ b/migration.c -@@ -274,7 +274,7 @@ static void migrate_fd_cleanup(void *opaque) - s->file = NULL; - } - -- assert(s->fd == -1); -+ assert(s->migration_file == NULL); - assert(s->state != MIG_STATE_ACTIVE); - - if (s->state != MIG_STATE_COMPLETED) { -@@ -330,8 +330,9 @@ static void migrate_fd_cancel(MigrationState *s) - int migrate_fd_close(MigrationState *s) - { - int rc = 0; -- if (s->fd != -1) { -- rc = s->close(s); -+ if (s->migration_file != NULL) { -+ rc = qemu_fclose(s->migration_file); -+ s->migration_file = NULL; - s->fd = -1; - } - return rc; -@@ -720,6 +721,7 @@ void migrate_fd_connect(MigrationState *s) - s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; - - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); -+ s->fd = qemu_get_fd(s->migration_file); - s->file = qemu_fopen_ops(s, &migration_file_ops); - - qemu_thread_create(&s->thread, migration_thread, s, -diff --git a/savevm.c b/savevm.c -index c60ace3..43963ce 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -400,6 +400,7 @@ QEMUFile *qemu_fopen_socket(int fd, const char *mode) - - s->fd = fd; - if (mode[0] == 'w') { -+ qemu_set_block(s->fd); - s->file = qemu_fopen_ops(s, &socket_write_ops); - } else { - s->file = qemu_fopen_ops(s, &socket_read_ops); diff --git a/0141-migration-use-QEMUFile-for-writing-outgoing-migratio.patch b/0141-migration-use-QEMUFile-for-writing-outgoing-migratio.patch deleted file mode 100644 index fe85309..0000000 --- a/0141-migration-use-QEMUFile-for-writing-outgoing-migratio.patch +++ /dev/null @@ -1,251 +0,0 @@ -From e15601079ef83c1fed53fb82d938bb2e4d6104ca Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:42 +0100 -Subject: [PATCH] migration: use QEMUFile for writing outgoing migration data - -Second, drop the file descriptor indirection, and write directly to the -QEMUFile. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit e6a1cf21328802f3a83e84e893b8cb8a468141cc) ---- - include/migration/migration.h | 4 ---- - migration-exec.c | 12 ----------- - migration-fd.c | 12 ----------- - migration-tcp.c | 12 ----------- - migration-unix.c | 12 ----------- - migration.c | 46 ++++++++----------------------------------- - 6 files changed, 8 insertions(+), 90 deletions(-) - -diff --git a/include/migration/migration.h b/include/migration/migration.h -index 1f8f305..ae94706 100644 ---- a/include/migration/migration.h -+++ b/include/migration/migration.h -@@ -40,10 +40,6 @@ struct MigrationState - QEMUFile *file; - QEMUFile *migration_file; - -- int fd; -- int (*get_error)(MigrationState *s); -- int (*write)(MigrationState *s, const void *buff, size_t size); -- - int state; - MigrationParams params; - int64_t total_time; -diff --git a/migration-exec.c b/migration-exec.c -index 8c3f720..1c539de 100644 ---- a/migration-exec.c -+++ b/migration-exec.c -@@ -33,16 +33,6 @@ - do { } while (0) - #endif - --static int file_errno(MigrationState *s) --{ -- return errno; --} -- --static int file_write(MigrationState *s, const void * buf, size_t size) --{ -- return write(s->fd, buf, size); --} -- - void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp) - { - s->migration_file = qemu_popen_cmd(command, "w"); -@@ -51,8 +41,6 @@ void exec_start_outgoing_migration(MigrationState *s, const char *command, Error - return; - } - -- s->get_error = file_errno; -- s->write = file_write; - migrate_fd_connect(s); - } - -diff --git a/migration-fd.c b/migration-fd.c -index 4636457..07c758a 100644 ---- a/migration-fd.c -+++ b/migration-fd.c -@@ -30,16 +30,6 @@ - do { } while (0) - #endif - --static int fd_errno(MigrationState *s) --{ -- return errno; --} -- --static int fd_write(MigrationState *s, const void * buf, size_t size) --{ -- return write(s->fd, buf, size); --} -- - void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) - { - int fd = monitor_get_fd(cur_mon, fdname, errp); -@@ -48,8 +38,6 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error ** - } - s->migration_file = qemu_fdopen(fd, "wb"); - -- s->get_error = fd_errno; -- s->write = fd_write; - migrate_fd_connect(s); - } - -diff --git a/migration-tcp.c b/migration-tcp.c -index 1e8e004..5ea4f3d 100644 ---- a/migration-tcp.c -+++ b/migration-tcp.c -@@ -29,16 +29,6 @@ - do { } while (0) - #endif - --static int socket_errno(MigrationState *s) --{ -- return socket_error(); --} -- --static int socket_write(MigrationState *s, const void * buf, size_t size) --{ -- return send(s->fd, buf, size, 0); --} -- - static void tcp_wait_for_connect(int fd, void *opaque) - { - MigrationState *s = opaque; -@@ -56,8 +46,6 @@ static void tcp_wait_for_connect(int fd, void *opaque) - - void tcp_start_outgoing_migration(MigrationState *s, const char *host_port, Error **errp) - { -- s->get_error = socket_errno; -- s->write = socket_write; - inet_nonblocking_connect(host_port, tcp_wait_for_connect, s, errp); - } - -diff --git a/migration-unix.c b/migration-unix.c -index 11917f4..64bfa31 100644 ---- a/migration-unix.c -+++ b/migration-unix.c -@@ -29,16 +29,6 @@ - do { } while (0) - #endif - --static int unix_errno(MigrationState *s) --{ -- return errno; --} -- --static int unix_write(MigrationState *s, const void * buf, size_t size) --{ -- return write(s->fd, buf, size); --} -- - static void unix_wait_for_connect(int fd, void *opaque) - { - MigrationState *s = opaque; -@@ -56,8 +46,6 @@ static void unix_wait_for_connect(int fd, void *opaque) - - void unix_start_outgoing_migration(MigrationState *s, const char *path, Error **errp) - { -- s->get_error = unix_errno; -- s->write = unix_write; - unix_nonblocking_connect(path, unix_wait_for_connect, s, errp); - } - -diff --git a/migration.c b/migration.c -index fa630ed..26ba6c9 100644 ---- a/migration.c -+++ b/migration.c -@@ -301,25 +301,6 @@ void migrate_fd_error(MigrationState *s) - notifier_list_notify(&migration_state_notifiers, s); - } - --static ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data, -- size_t size) --{ -- ssize_t ret; -- -- if (s->state != MIG_STATE_ACTIVE) { -- return -EIO; -- } -- -- do { -- ret = s->write(s, data, size); -- } while (ret == -1 && ((s->get_error(s)) == EINTR)); -- -- if (ret == -1) -- ret = -(s->get_error(s)); -- -- return ret; --} -- - static void migrate_fd_cancel(MigrationState *s) - { - DPRINTF("cancelling migration\n"); -@@ -333,7 +314,6 @@ int migrate_fd_close(MigrationState *s) - if (s->migration_file != NULL) { - rc = qemu_fclose(s->migration_file); - s->migration_file = NULL; -- s->fd = -1; - } - return rc; - } -@@ -519,8 +499,7 @@ static int migration_put_buffer(void *opaque, const uint8_t *buf, - int64_t pos, int size) - { - MigrationState *s = opaque; -- ssize_t ret; -- size_t sent; -+ int ret; - - DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); - -@@ -528,22 +507,14 @@ static int migration_put_buffer(void *opaque, const uint8_t *buf, - return size; - } - -- sent = 0; -- while (size) { -- ret = migrate_fd_put_buffer(s, buf, size); -- if (ret <= 0) { -- DPRINTF("error flushing data, %zd\n", ret); -- return ret; -- } else { -- DPRINTF("flushed %zd byte(s)\n", ret); -- sent += ret; -- buf += ret; -- size -= ret; -- s->bytes_xfer += ret; -- } -+ qemu_put_buffer(s->migration_file, buf, size); -+ ret = qemu_file_get_error(s->migration_file); -+ if (ret) { -+ return ret; - } - -- return sent; -+ s->bytes_xfer += size; -+ return size; - } - - static int migration_close(void *opaque) -@@ -564,7 +535,7 @@ static int migration_get_fd(void *opaque) - { - MigrationState *s = opaque; - -- return s->fd; -+ return qemu_get_fd(s->migration_file); - } - - /* -@@ -721,7 +692,6 @@ void migrate_fd_connect(MigrationState *s) - s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; - - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); -- s->fd = qemu_get_fd(s->migration_file); - s->file = qemu_fopen_ops(s, &migration_file_ops); - - qemu_thread_create(&s->thread, migration_thread, s, diff --git a/0142-migration-use-qemu_ftell-to-compute-bandwidth.patch b/0142-migration-use-qemu_ftell-to-compute-bandwidth.patch deleted file mode 100644 index dbbf1b1..0000000 --- a/0142-migration-use-qemu_ftell-to-compute-bandwidth.patch +++ /dev/null @@ -1,45 +0,0 @@ -From c6c8a4fa26f5aa2f687a779997a2bd040cd01ff4 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:43 +0100 -Subject: [PATCH] migration: use qemu_ftell to compute bandwidth - -Prepare for when s->bytes_xfer will be removed. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit be7172e22a9c3bc448894e57f6c2d1af6ffd47fd) ---- - migration.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/migration.c b/migration.c -index 26ba6c9..def1e9e 100644 ---- a/migration.c -+++ b/migration.c -@@ -589,6 +589,7 @@ static void *migration_thread(void *opaque) - MigrationState *s = opaque; - int64_t initial_time = qemu_get_clock_ms(rt_clock); - int64_t sleep_time = 0; -+ int64_t initial_bytes = 0; - int64_t max_size = 0; - int64_t start_time = initial_time; - bool old_vm_running = false; -@@ -629,7 +630,7 @@ static void *migration_thread(void *opaque) - } - current_time = qemu_get_clock_ms(rt_clock); - if (current_time >= initial_time + BUFFER_DELAY) { -- uint64_t transferred_bytes = s->bytes_xfer; -+ uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes; - uint64_t time_spent = current_time - initial_time - sleep_time; - double bandwidth = transferred_bytes / time_spent; - max_size = bandwidth * migrate_max_downtime() / 1000000; -@@ -646,6 +647,7 @@ static void *migration_thread(void *opaque) - s->bytes_xfer = 0; - sleep_time = 0; - initial_time = current_time; -+ initial_bytes = qemu_ftell(s->file); - } - if (qemu_file_rate_limit(s->file)) { - /* usleep expects microseconds */ diff --git a/0143-migration-small-changes-around-rate-limiting.patch b/0143-migration-small-changes-around-rate-limiting.patch deleted file mode 100644 index 1f42fd1..0000000 --- a/0143-migration-small-changes-around-rate-limiting.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 6709fac663d343a1f34178da389001d46df3cac9 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:44 +0100 -Subject: [PATCH] migration: small changes around rate-limiting - -This patch extracts a few small changes from the next patch, which -are unrelated to adding generic rate-limiting functionality to -QEMUFile. Make migration_set_rate_limit a simple accessor, and -use qemu_file_set_rate_limit consistently. Also fix a typo where -INT_MAX should have been SIZE_MAX. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 442773cef15092b5927851237850760345d2cf16) ---- - migration.c | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/migration.c b/migration.c -index def1e9e..5c7d04f 100644 ---- a/migration.c -+++ b/migration.c -@@ -462,10 +462,15 @@ void qmp_migrate_set_speed(int64_t value, Error **errp) - if (value < 0) { - value = 0; - } -+ if (value > SIZE_MAX) { -+ value = SIZE_MAX; -+ } - - s = migrate_get_current(); - s->bandwidth_limit = value; -- qemu_file_set_rate_limit(s->file, s->bandwidth_limit); -+ if (s->file) { -+ qemu_file_set_rate_limit(s->file, s->bandwidth_limit / XFER_LIMIT_RATIO); -+ } - } - - void qmp_migrate_set_downtime(double value, Error **errp) -@@ -567,11 +572,8 @@ static int64_t migration_set_rate_limit(void *opaque, int64_t new_rate) - if (qemu_file_get_error(s->file)) { - goto out; - } -- if (new_rate > SIZE_MAX) { -- new_rate = SIZE_MAX; -- } - -- s->xfer_limit = new_rate / XFER_LIMIT_RATIO; -+ s->xfer_limit = new_rate; - - out: - return s->xfer_limit; -@@ -614,7 +616,7 @@ static void *migration_thread(void *opaque) - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); - old_vm_running = runstate_is_running(); - vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); -- s->xfer_limit = INT_MAX; -+ qemu_file_set_rate_limit(s->file, INT_MAX); - qemu_savevm_state_complete(s->file); - qemu_mutex_unlock_iothread(); - if (!qemu_file_get_error(s->file)) { -@@ -691,11 +693,12 @@ void migrate_fd_connect(MigrationState *s) - /* This is a best 1st approximation. ns to ms */ - s->expected_downtime = max_downtime/1000000; - -- s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; -- - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); - s->file = qemu_fopen_ops(s, &migration_file_ops); - -+ qemu_file_set_rate_limit(s->file, -+ s->bandwidth_limit / XFER_LIMIT_RATIO); -+ - qemu_thread_create(&s->thread, migration_thread, s, - QEMU_THREAD_JOINABLE); - notifier_list_notify(&migration_state_notifiers, s); diff --git a/0144-migration-move-rate-limiting-to-QEMUFile.patch b/0144-migration-move-rate-limiting-to-QEMUFile.patch deleted file mode 100644 index 74207bb..0000000 --- a/0144-migration-move-rate-limiting-to-QEMUFile.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 9324971693642bf648f60b3598a8b588bef000e8 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:45 +0100 -Subject: [PATCH] migration: move rate limiting to QEMUFile - -Rate limiting is now simply a byte counter; client call -qemu_file_rate_limit() manually to determine if they have to exit. -So it is possible and simple to move the functionality to QEMUFile. - -This makes the remaining functionality of s->file redundant; -in the next patch we can remove it and write directly to s->migration_file. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 1964a397063967acc5ce71a2a24ed26e74824ee1) ---- - docs/migration.txt | 20 +---------------- - include/migration/qemu-file.h | 18 ++------------- - migration.c | 51 +------------------------------------------ - savevm.c | 31 ++++++++++++++------------ - 4 files changed, 21 insertions(+), 99 deletions(-) - -diff --git a/docs/migration.txt b/docs/migration.txt -index f3ddd2f..0719a55 100644 ---- a/docs/migration.txt -+++ b/docs/migration.txt -@@ -55,10 +55,7 @@ QEMUFile with: - QEMUFile *qemu_fopen_ops(void *opaque, - QEMUFilePutBufferFunc *put_buffer, - QEMUFileGetBufferFunc *get_buffer, -- QEMUFileCloseFunc *close, -- QEMUFileRateLimit *rate_limit, -- QEMUFileSetRateLimit *set_rate_limit, -- QEMUFileGetRateLimit *get_rate_limit); -+ QEMUFileCloseFunc *close); - - The functions have the following functionality: - -@@ -80,24 +77,9 @@ Close a file and return an error code. - - typedef int (QEMUFileCloseFunc)(void *opaque); - --Called to determine if the file has exceeded its bandwidth allocation. The --bandwidth capping is a soft limit, not a hard limit. -- --typedef int (QEMUFileRateLimit)(void *opaque); -- --Called to change the current bandwidth allocation. This function must return --the new actual bandwidth. It should be new_rate if everything goes OK, and --the old rate otherwise. -- --typedef size_t (QEMUFileSetRateLimit)(void *opaque, size_t new_rate); --typedef size_t (QEMUFileGetRateLimit)(void *opaque); -- - You can use any internal state that you need using the opaque void * - pointer that is passed to all functions. - --The rate limiting functions are used to limit the bandwidth used by --QEMU migration. -- - The important functions for us are put_buffer()/get_buffer() that - allow to write/read a buffer into the QEMUFile. - -diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h -index 25e8461..df81261 100644 ---- a/include/migration/qemu-file.h -+++ b/include/migration/qemu-file.h -@@ -51,26 +51,11 @@ typedef int (QEMUFileCloseFunc)(void *opaque); - */ - typedef int (QEMUFileGetFD)(void *opaque); - --/* Called to determine if the file has exceeded its bandwidth allocation. The -- * bandwidth capping is a soft limit, not a hard limit. -- */ --typedef int (QEMUFileRateLimit)(void *opaque); -- --/* Called to change the current bandwidth allocation. This function must return -- * the new actual bandwidth. It should be new_rate if everything goes ok, and -- * the old rate otherwise -- */ --typedef int64_t (QEMUFileSetRateLimit)(void *opaque, int64_t new_rate); --typedef int64_t (QEMUFileGetRateLimit)(void *opaque); -- - typedef struct QEMUFileOps { - QEMUFilePutBufferFunc *put_buffer; - QEMUFileGetBufferFunc *get_buffer; - QEMUFileCloseFunc *close; - QEMUFileGetFD *get_fd; -- QEMUFileRateLimit *rate_limit; -- QEMUFileSetRateLimit *set_rate_limit; -- QEMUFileGetRateLimit *get_rate_limit; - } QEMUFileOps; - - QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops); -@@ -109,7 +94,8 @@ unsigned int qemu_get_be32(QEMUFile *f); - uint64_t qemu_get_be64(QEMUFile *f); - - int qemu_file_rate_limit(QEMUFile *f); --int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); -+void qemu_file_reset_rate_limit(QEMUFile *f); -+void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); - int64_t qemu_file_get_rate_limit(QEMUFile *f); - int qemu_file_get_error(QEMUFile *f); - -diff --git a/migration.c b/migration.c -index 5c7d04f..ea84008 100644 ---- a/migration.c -+++ b/migration.c -@@ -518,7 +518,6 @@ static int migration_put_buffer(void *opaque, const uint8_t *buf, - return ret; - } - -- s->bytes_xfer += size; - return size; - } - -@@ -543,49 +542,6 @@ static int migration_get_fd(void *opaque) - return qemu_get_fd(s->migration_file); - } - --/* -- * The meaning of the return values is: -- * 0: We can continue sending -- * 1: Time to stop -- * negative: There has been an error -- */ --static int migration_rate_limit(void *opaque) --{ -- MigrationState *s = opaque; -- int ret; -- -- ret = qemu_file_get_error(s->file); -- if (ret) { -- return ret; -- } -- -- if (s->bytes_xfer >= s->xfer_limit) { -- return 1; -- } -- -- return 0; --} -- --static int64_t migration_set_rate_limit(void *opaque, int64_t new_rate) --{ -- MigrationState *s = opaque; -- if (qemu_file_get_error(s->file)) { -- goto out; -- } -- -- s->xfer_limit = new_rate; -- --out: -- return s->xfer_limit; --} -- --static int64_t migration_get_rate_limit(void *opaque) --{ -- MigrationState *s = opaque; -- -- return s->xfer_limit; --} -- - static void *migration_thread(void *opaque) - { - MigrationState *s = opaque; -@@ -646,7 +602,7 @@ static void *migration_thread(void *opaque) - s->expected_downtime = s->dirty_bytes_rate / bandwidth; - } - -- s->bytes_xfer = 0; -+ qemu_file_reset_rate_limit(s->file); - sleep_time = 0; - initial_time = current_time; - initial_bytes = qemu_ftell(s->file); -@@ -679,9 +635,6 @@ static const QEMUFileOps migration_file_ops = { - .get_fd = migration_get_fd, - .put_buffer = migration_put_buffer, - .close = migration_close, -- .rate_limit = migration_rate_limit, -- .get_rate_limit = migration_get_rate_limit, -- .set_rate_limit = migration_set_rate_limit, - }; - - void migrate_fd_connect(MigrationState *s) -@@ -689,10 +642,8 @@ void migrate_fd_connect(MigrationState *s) - s->state = MIG_STATE_ACTIVE; - trace_migrate_set_state(MIG_STATE_ACTIVE); - -- s->bytes_xfer = 0; - /* This is a best 1st approximation. ns to ms */ - s->expected_downtime = max_downtime/1000000; -- - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); - s->file = qemu_fopen_ops(s, &migration_file_ops); - -diff --git a/savevm.c b/savevm.c -index 43963ce..e9471a5 100644 ---- a/savevm.c -+++ b/savevm.c -@@ -119,6 +119,9 @@ struct QEMUFile { - void *opaque; - int is_write; - -+ int64_t bytes_xfer; -+ int64_t xfer_limit; -+ - int64_t pos; /* start of buffer when writing, end of buffer - when reading */ - int buf_index; -@@ -479,7 +482,6 @@ QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops) - f->opaque = opaque; - f->ops = ops; - f->is_write = 0; -- - return f; - } - -@@ -605,6 +607,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) - memcpy(f->buf + f->buf_index, buf, l); - f->is_write = 1; - f->buf_index += l; -+ f->bytes_xfer += l; - buf += l; - size -= l; - if (f->buf_index >= IO_BUF_SIZE) { -@@ -725,28 +728,28 @@ int64_t qemu_ftell(QEMUFile *f) - - int qemu_file_rate_limit(QEMUFile *f) - { -- if (f->ops->rate_limit) -- return f->ops->rate_limit(f->opaque); -- -+ if (qemu_file_get_error(f)) { -+ return 1; -+ } -+ if (f->xfer_limit > 0 && f->bytes_xfer > f->xfer_limit) { -+ return 1; -+ } - return 0; - } - - int64_t qemu_file_get_rate_limit(QEMUFile *f) - { -- if (f->ops->get_rate_limit) -- return f->ops->get_rate_limit(f->opaque); -- -- return 0; -+ return f->xfer_limit; - } - --int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate) -+void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit) - { -- /* any failed or completed migration keeps its state to allow probing of -- * migration data, but has no associated file anymore */ -- if (f && f->ops->set_rate_limit) -- return f->ops->set_rate_limit(f->opaque, new_rate); -+ f->xfer_limit = limit; -+} - -- return 0; -+void qemu_file_reset_rate_limit(QEMUFile *f) -+{ -+ f->bytes_xfer = 0; - } - - void qemu_put_be16(QEMUFile *f, unsigned int v) diff --git a/0145-migration-move-contents-of-migration_close-to-migrat.patch b/0145-migration-move-contents-of-migration_close-to-migrat.patch deleted file mode 100644 index beb8326..0000000 --- a/0145-migration-move-contents-of-migration_close-to-migrat.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 2b2c8310a60981dfe3bb37cdd007016f285d1b8a Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:46 +0100 -Subject: [PATCH] migration: move contents of migration_close to - migrate_fd_cleanup - -With this patch, the migration_file is not needed anymore. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 404a7c05bcc20c51fe1a9bf2deaeb4d6b658d3a3) ---- - migration.c | 17 +++++++---------- - 1 file changed, 7 insertions(+), 10 deletions(-) - -diff --git a/migration.c b/migration.c -index ea84008..949a5bc 100644 ---- a/migration.c -+++ b/migration.c -@@ -272,6 +272,12 @@ static void migrate_fd_cleanup(void *opaque) - DPRINTF("closing file\n"); - qemu_fclose(s->file); - s->file = NULL; -+ -+ qemu_mutex_unlock_iothread(); -+ qemu_thread_join(&s->thread); -+ qemu_mutex_lock_iothread(); -+ -+ migrate_fd_close(s); - } - - assert(s->migration_file == NULL); -@@ -523,16 +529,7 @@ static int migration_put_buffer(void *opaque, const uint8_t *buf, - - static int migration_close(void *opaque) - { -- MigrationState *s = opaque; -- -- DPRINTF("closing\n"); -- -- qemu_mutex_unlock_iothread(); -- qemu_thread_join(&s->thread); -- qemu_mutex_lock_iothread(); -- assert(s->state != MIG_STATE_ACTIVE); -- -- return migrate_fd_close(s); -+ return 0; - } - - static int migration_get_fd(void *opaque) diff --git a/0146-migration-eliminate-s-migration_file.patch b/0146-migration-eliminate-s-migration_file.patch deleted file mode 100644 index 894aebf..0000000 --- a/0146-migration-eliminate-s-migration_file.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 2e690b6127da765a58b4f69e7bc79c8abfa03551 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:47 +0100 -Subject: [PATCH] migration: eliminate s->migration_file - -The indirection is useless now. Backends can open s->file directly. - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit b352365f5abec075dede0222f1bc37674d64117c) ---- - include/migration/migration.h | 2 -- - migration-exec.c | 4 ++-- - migration-fd.c | 2 +- - migration-tcp.c | 4 ++-- - migration-unix.c | 4 ++-- - migration.c | 51 ++++--------------------------------------- - 6 files changed, 11 insertions(+), 56 deletions(-) - -diff --git a/include/migration/migration.h b/include/migration/migration.h -index ae94706..bb617fd 100644 ---- a/include/migration/migration.h -+++ b/include/migration/migration.h -@@ -36,9 +36,7 @@ struct MigrationState - size_t xfer_limit; - QemuThread thread; - QEMUBH *cleanup_bh; -- - QEMUFile *file; -- QEMUFile *migration_file; - - int state; - MigrationParams params; -diff --git a/migration-exec.c b/migration-exec.c -index 1c539de..deab4e3 100644 ---- a/migration-exec.c -+++ b/migration-exec.c -@@ -35,8 +35,8 @@ - - void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp) - { -- s->migration_file = qemu_popen_cmd(command, "w"); -- if (s->migration_file == NULL) { -+ s->file = qemu_popen_cmd(command, "w"); -+ if (s->file == NULL) { - error_setg_errno(errp, errno, "failed to popen the migration target"); - return; - } -diff --git a/migration-fd.c b/migration-fd.c -index 07c758a..3d4613c 100644 ---- a/migration-fd.c -+++ b/migration-fd.c -@@ -36,7 +36,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error ** - if (fd == -1) { - return; - } -- s->migration_file = qemu_fdopen(fd, "wb"); -+ s->file = qemu_fdopen(fd, "wb"); - - migrate_fd_connect(s); - } -diff --git a/migration-tcp.c b/migration-tcp.c -index 5ea4f3d..b20ee58 100644 ---- a/migration-tcp.c -+++ b/migration-tcp.c -@@ -35,11 +35,11 @@ static void tcp_wait_for_connect(int fd, void *opaque) - - if (fd < 0) { - DPRINTF("migrate connect error\n"); -- s->migration_file = NULL; -+ s->file = NULL; - migrate_fd_error(s); - } else { - DPRINTF("migrate connect success\n"); -- s->migration_file = qemu_fopen_socket(fd, "wb"); -+ s->file = qemu_fopen_socket(fd, "wb"); - migrate_fd_connect(s); - } - } -diff --git a/migration-unix.c b/migration-unix.c -index 64bfa31..94b7022 100644 ---- a/migration-unix.c -+++ b/migration-unix.c -@@ -35,11 +35,11 @@ static void unix_wait_for_connect(int fd, void *opaque) - - if (fd < 0) { - DPRINTF("migrate connect error\n"); -- s->migration_file = NULL; -+ s->file = NULL; - migrate_fd_error(s); - } else { - DPRINTF("migrate connect success\n"); -- s->migration_file = qemu_fopen_socket(fd, "wb"); -+ s->file = qemu_fopen_socket(fd, "wb"); - migrate_fd_connect(s); - } - } -diff --git a/migration.c b/migration.c -index 949a5bc..68ce4c9 100644 ---- a/migration.c -+++ b/migration.c -@@ -270,9 +270,6 @@ static void migrate_fd_cleanup(void *opaque) - - if (s->file) { - DPRINTF("closing file\n"); -- qemu_fclose(s->file); -- s->file = NULL; -- - qemu_mutex_unlock_iothread(); - qemu_thread_join(&s->thread); - qemu_mutex_lock_iothread(); -@@ -280,7 +277,7 @@ static void migrate_fd_cleanup(void *opaque) - migrate_fd_close(s); - } - -- assert(s->migration_file == NULL); -+ assert(s->file == NULL); - assert(s->state != MIG_STATE_ACTIVE); - - if (s->state != MIG_STATE_COMPLETED) { -@@ -317,9 +314,9 @@ static void migrate_fd_cancel(MigrationState *s) - int migrate_fd_close(MigrationState *s) - { - int rc = 0; -- if (s->migration_file != NULL) { -- rc = qemu_fclose(s->migration_file); -- s->migration_file = NULL; -+ if (s->file != NULL) { -+ rc = qemu_fclose(s->file); -+ s->file = NULL; - } - return rc; - } -@@ -506,39 +503,6 @@ int64_t migrate_xbzrle_cache_size(void) - - /* migration thread support */ - --static int migration_put_buffer(void *opaque, const uint8_t *buf, -- int64_t pos, int size) --{ -- MigrationState *s = opaque; -- int ret; -- -- DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); -- -- if (size <= 0) { -- return size; -- } -- -- qemu_put_buffer(s->migration_file, buf, size); -- ret = qemu_file_get_error(s->migration_file); -- if (ret) { -- return ret; -- } -- -- return size; --} -- --static int migration_close(void *opaque) --{ -- return 0; --} -- --static int migration_get_fd(void *opaque) --{ -- MigrationState *s = opaque; -- -- return qemu_get_fd(s->migration_file); --} -- - static void *migration_thread(void *opaque) - { - MigrationState *s = opaque; -@@ -628,12 +592,6 @@ static void *migration_thread(void *opaque) - return NULL; - } - --static const QEMUFileOps migration_file_ops = { -- .get_fd = migration_get_fd, -- .put_buffer = migration_put_buffer, -- .close = migration_close, --}; -- - void migrate_fd_connect(MigrationState *s) - { - s->state = MIG_STATE_ACTIVE; -@@ -642,7 +600,6 @@ void migrate_fd_connect(MigrationState *s) - /* This is a best 1st approximation. ns to ms */ - s->expected_downtime = max_downtime/1000000; - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); -- s->file = qemu_fopen_ops(s, &migration_file_ops); - - qemu_file_set_rate_limit(s->file, - s->bandwidth_limit / XFER_LIMIT_RATIO); diff --git a/0147-migration-inline-migrate_fd_close.patch b/0147-migration-inline-migrate_fd_close.patch deleted file mode 100644 index 1b4e43e..0000000 --- a/0147-migration-inline-migrate_fd_close.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 4c0d468f2aed75305117ea9860af21c32a915041 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 22 Feb 2013 17:36:48 +0100 -Subject: [PATCH] migration: inline migrate_fd_close - -Reviewed-by: Orit Wasserman -Reviewed-by: Juan Quintela -Signed-off-by: Paolo Bonzini -Signed-off-by: Juan Quintela -(cherry picked from commit 6f190a0641f5b06a462b62955c15c77b8fb3990c) ---- - migration.c | 14 ++------------ - 1 file changed, 2 insertions(+), 12 deletions(-) - -diff --git a/migration.c b/migration.c -index 68ce4c9..0aff06d 100644 ---- a/migration.c -+++ b/migration.c -@@ -274,10 +274,10 @@ static void migrate_fd_cleanup(void *opaque) - qemu_thread_join(&s->thread); - qemu_mutex_lock_iothread(); - -- migrate_fd_close(s); -+ qemu_fclose(s->file); -+ s->file = NULL; - } - -- assert(s->file == NULL); - assert(s->state != MIG_STATE_ACTIVE); - - if (s->state != MIG_STATE_COMPLETED) { -@@ -311,16 +311,6 @@ static void migrate_fd_cancel(MigrationState *s) - migrate_finish_set_state(s, MIG_STATE_CANCELLED); - } - --int migrate_fd_close(MigrationState *s) --{ -- int rc = 0; -- if (s->file != NULL) { -- rc = qemu_fclose(s->file); -- s->file = NULL; -- } -- return rc; --} -- - void add_migration_state_change_notifier(Notifier *notify) - { - notifier_list_add(&migration_state_notifiers, notify); diff --git a/0148-Revert-migration-don-t-account-sleep-time-for-calcul.patch b/0148-Revert-migration-don-t-account-sleep-time-for-calcul.patch deleted file mode 100644 index 1e4356b..0000000 --- a/0148-Revert-migration-don-t-account-sleep-time-for-calcul.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 45d723c48255328fbd5128c4c70c91103e420590 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 16 May 2013 16:25:44 -0500 -Subject: [PATCH] Revert "migration: don't account sleep time for calculating - bandwidth" - -This reverts commit 7161082c8d8cf167c508976887a0a63f4db92b51. - -Reverting this patch fixes a divide-by-zero error in qemu that can be -fairly reliably triggered by doing block migration. In this case, the -configuration/error was: - -source: temp/x86_64-softmmu/qemu-system-x86_64 -enable-kvm -L temp-bios --M pc-i440fx-1.4 -m 512M -kernel boot/vmlinuz-x86_64 -initrd -boot/test-initramfs-x86_64.img.gz -vga std -append seed=1234 -drive -file=disk1.img,if=virtio -drive file=disk2.img,if=virtio -device -virtio-net-pci,netdev=net0 -netdev user,id=net0 -monitor -unix:/tmp/vm-hmp.sock,server,nowait -qmp -unix:/tmp/vm-qmp.sock,server,nowait -vnc :100 - -16837 Floating point exception(core dumped) - -target: temp/x86_64-softmmu/qemu-system-x86_64 -enable-kvm -L temp-bios --M pc-i440fx-1.4 -m 512M -kernel boot/vmlinuz-x86_64 -initrd -boot/test-initramfs-x86_64.img.gz -vga std -append seed=1234 -drive -file=target_disk1.img,if=virtio -drive file=target_disk2.img,if=virtio --device virtio-net-pci,netdev=net0 -netdev user,id=net0 -incoming -unix:/tmp/migrate.sock -monitor -unix:/tmp/vm-hmp-incoming.sock,server,nowait -qmp -unix:/tmp/vm-qmp-incoming.sock,server,nowait -vnc :101 - -Receiving block device images -20 % -21 % -load of migration failed - -This revert potentially re-introduces a bug that was present in 1.4, -but fixes a prevalent issue with block migration so we should revert -it for now and take an updated patch later. - -Conflicts: - - migration.c - -* fixed up to remove logic introduced in 7161082c while leaving - changes in HEAD intact - -Signed-off-by: Michael Roth -Message-id: 1368739544-31021-1-git-send-email-mdroth@linux.vnet.ibm.com -Signed-off-by: Anthony Liguori -(cherry picked from commit 77417f10701d330c7005b0f0a2c0cef9e05d430d) ---- - migration.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/migration.c b/migration.c -index 0aff06d..cca6df6 100644 ---- a/migration.c -+++ b/migration.c -@@ -497,7 +497,6 @@ static void *migration_thread(void *opaque) - { - MigrationState *s = opaque; - int64_t initial_time = qemu_get_clock_ms(rt_clock); -- int64_t sleep_time = 0; - int64_t initial_bytes = 0; - int64_t max_size = 0; - int64_t start_time = initial_time; -@@ -540,7 +539,7 @@ static void *migration_thread(void *opaque) - current_time = qemu_get_clock_ms(rt_clock); - if (current_time >= initial_time + BUFFER_DELAY) { - uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes; -- uint64_t time_spent = current_time - initial_time - sleep_time; -+ uint64_t time_spent = current_time - initial_time; - double bandwidth = transferred_bytes / time_spent; - max_size = bandwidth * migrate_max_downtime() / 1000000; - -@@ -554,14 +553,12 @@ static void *migration_thread(void *opaque) - } - - qemu_file_reset_rate_limit(s->file); -- sleep_time = 0; - initial_time = current_time; - initial_bytes = qemu_ftell(s->file); - } - if (qemu_file_rate_limit(s->file)) { - /* usleep expects microseconds */ - g_usleep((initial_time + BUFFER_DELAY - current_time)*1000); -- sleep_time += qemu_get_clock_ms(rt_clock) - current_time; - } - } - diff --git a/0201-configure-Add-enable-migration-from-qemu-kvm.patch b/0201-configure-Add-enable-migration-from-qemu-kvm.patch deleted file mode 100644 index 3b5b625..0000000 --- a/0201-configure-Add-enable-migration-from-qemu-kvm.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 7daeb79e054ba552bd598557a3373325727d2231 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Tue, 19 Feb 2013 14:39:05 -0500 -Subject: [PATCH] configure: Add --enable-migration-from-qemu-kvm - -This switch will turn on all the migration compat bits needed to -perform migration from qemu-kvm to qemu. It's just a stub for now. - -This compat will break incoming migration from qemu < 1.3, but for -distros where qemu-kvm was the only shipped package for years it's -not a big loss (and I don't know any way to avoid it). - -Signed-off-by: Cole Robinson ---- - configure | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/configure b/configure -index f4097ef..bc2870b 100755 ---- a/configure -+++ b/configure -@@ -170,6 +170,7 @@ xfs="" - - vhost_net="no" - kvm="no" -+migrate_from_kvm="no" - gprof="no" - debug_tcg="no" - debug="no" -@@ -759,6 +760,8 @@ for opt do - ;; - --enable-kvm) kvm="yes" - ;; -+ --enable-migration-from-qemu-kvm) migrate_from_kvm="yes" -+ ;; - --disable-tcg-interpreter) tcg_interpreter="no" - ;; - --enable-tcg-interpreter) tcg_interpreter="yes" -@@ -1087,6 +1090,9 @@ echo " --enable-bluez enable bluez stack connectivity" - echo " --disable-slirp disable SLIRP userspace network connectivity" - echo " --disable-kvm disable KVM acceleration support" - echo " --enable-kvm enable KVM acceleration support" -+echo " --enable-migration-from-qemu-kvm Allow migration from qemu-kvm." -+echo " This will break migration from " -+echo " qemu < 1.3 in most cases" - echo " --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)" - echo " --disable-nptl disable usermode NPTL support" - echo " --enable-nptl enable usermode NPTL support" -@@ -3358,6 +3364,7 @@ echo "Linux AIO support $linux_aio" - echo "ATTR/XATTR support $attr" - echo "Install blobs $blobs" - echo "KVM support $kvm" -+echo "Migrate from qemu-kvm $migrate_from_kvm" - echo "TCG interpreter $tcg_interpreter" - echo "fdt support $fdt" - echo "preadv support $preadv" -@@ -3646,6 +3653,9 @@ fi - if test "$signalfd" = "yes" ; then - echo "CONFIG_SIGNALFD=y" >> $config_host_mak - fi -+if test "$migrate_from_kvm" = "yes"; then -+ echo "CONFIG_MIGRATE_FROM_QEMU_KVM=y" >> $config_host_mak -+fi - if test "$tcg_interpreter" = "yes" ; then - echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak - fi diff --git a/0202-acpi_piix4-Drop-minimum_version_id-to-handle-qemu-kv.patch b/0202-acpi_piix4-Drop-minimum_version_id-to-handle-qemu-kv.patch deleted file mode 100644 index babe998..0000000 --- a/0202-acpi_piix4-Drop-minimum_version_id-to-handle-qemu-kv.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b94ccea34cf71689a751fcec9fb7afb417ce7442 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Tue, 19 Feb 2013 14:44:49 -0500 -Subject: [PATCH] acpi_piix4: Drop minimum_version_id to handle qemu-kvm - migration - -qemu-kvm 1.2 advertised version_id=2, but it was not the same -format as qemu.git version_id=2. - -commit b0b873a07872f7ab7f66f259c73fb9dd42aa66a9 added the qemu-kvm -format to qemu.git, but was forced to call it version_id=3, and -bumped minimum_version_id to 3. This breaks incoming migration from -qemu-kvm. - -If --enable-migration-from-qemu-kvm is enabled, drop minimum_version_id -to 2. Migration from qemu-kvm version_id=2 and qemu 1.3+ version_id=3 -works, but migration from qemu < 1.3 is broken. - -Signed-off-by: Cole Robinson ---- - hw/acpi_piix4.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - -diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c -index 1beac21..2abcc9d 100644 ---- a/hw/acpi_piix4.c -+++ b/hw/acpi_piix4.c -@@ -257,16 +257,19 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) - return ret; - } - --/* qemu-kvm 1.2 uses version 3 but advertised as 2 -- * To support incoming qemu-kvm 1.2 migration, change version_id -- * and minimum_version_id to 2 below (which breaks migration from -- * qemu 1.2). -- * -- */ - static const VMStateDescription vmstate_acpi = { - .name = "piix4_pm", - .version_id = 3, -+#ifdef CONFIG_MIGRATE_FROM_QEMU_KVM -+ /* -+ * qemu-kvm 1.2 uses qemu.git version 3 format, but advertised as 2. -+ * This allows incoming migration from qemu-kvm, but breaks incoming -+ * migration from qemu < 1.3. -+ */ -+ .minimum_version_id = 2, -+#else - .minimum_version_id = 3, -+#endif - .minimum_version_id_old = 1, - .load_state_old = acpi_load_old, - .post_load = vmstate_acpi_post_load, diff --git a/0203-i8254-Fix-migration-from-qemu-kvm-1.1.patch b/0203-i8254-Fix-migration-from-qemu-kvm-1.1.patch deleted file mode 100644 index 272298b..0000000 --- a/0203-i8254-Fix-migration-from-qemu-kvm-1.1.patch +++ /dev/null @@ -1,36 +0,0 @@ -From fb124a30d5b7eff071122fd6236ebbcf8cbeaf46 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Tue, 19 Feb 2013 15:04:59 -0500 -Subject: [PATCH] i8254: Fix migration from qemu-kvm < 1.1 - -qemu-kvm commit 81bdec908fb2be0ccaff1d4ee67956c509e440ad did this, -but the logic can't be carried unconditionally in qemu.git without -breaking migration from qemu < 1.1. - -Conditionalize it with --enable-migrate-from-qemu-kvm - -Signed-off-by: Cole Robinson ---- - hw/i8254_common.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/i8254_common.c b/hw/i8254_common.c -index 8c2e45a..072fa09 100644 ---- a/hw/i8254_common.c -+++ b/hw/i8254_common.c -@@ -275,7 +275,15 @@ static const VMStateDescription vmstate_pit_common = { - .pre_save = pit_dispatch_pre_save, - .post_load = pit_dispatch_post_load, - .fields = (VMStateField[]) { -+#ifdef CONFIG_MIGRATE_FROM_QEMU_KVM -+ /* qemu-kvm version_id=2 had 'flags' here which is equivalent -+ * This fixes incoming migration from qemu-kvm 1.0, but breaks -+ * incoming migration from qemu < 1.1 -+ */ -+ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), -+#else - VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), -+#endif - VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, - vmstate_pit_channel, PITChannelState), - VMSTATE_INT64(channels[0].next_transition_time, diff --git a/0204-pc_piix-Add-compat-handling-for-qemu-kvm-VGA-mem-siz.patch b/0204-pc_piix-Add-compat-handling-for-qemu-kvm-VGA-mem-siz.patch deleted file mode 100644 index c3ecef4..0000000 --- a/0204-pc_piix-Add-compat-handling-for-qemu-kvm-VGA-mem-siz.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 296b2d495cca8331481939dce7f2c04f4d640366 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Tue, 19 Feb 2013 15:35:40 -0500 -Subject: [PATCH] pc_piix: Add compat handling for qemu-kvm VGA mem size - -Paolo outlines this here: - -https://lists.gnu.org/archive/html/qemu-devel/2013-01/msg02540.html - -qemu-kvm defaulted to vgamem=16MB since at least 0.15, while qemu used -8MB. For qemu 1.2, the default was changed to 16MB for all devices -except cirrus. - -If --enable-migration-from-qemu-kvm is specified, make sure cirrus -uses 16MB for <= pc-1.2 (the qemu-kvm merge), and 16MB always for -all others. This will break incoming qemu migration for qemu < 1.3. - -Signed-off-by: Cole Robinson ---- - hw/pc_piix.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - -diff --git a/hw/pc_piix.c b/hw/pc_piix.c -index 0af436c..e3f8e96 100644 ---- a/hw/pc_piix.c -+++ b/hw/pc_piix.c -@@ -331,6 +331,13 @@ static QEMUMachine pc_machine_v1_3 = { - DEFAULT_MACHINE_OPTIONS, - }; - -+#ifdef CONFIG_MIGRATE_FROM_QEMU_KVM -+/* qemu-kvm defaulted to 16MB video memory since 0.15 at least. */ -+# define OLD_VGA_MEM stringify(16) -+#else -+# define OLD_VGA_MEM stringify(8) -+#endif -+ - #define PC_COMPAT_1_2 \ - PC_COMPAT_1_3,\ - {\ -@@ -354,6 +361,10 @@ static QEMUMachine pc_machine_v1_3 = { - .property = "revision",\ - .value = stringify(3),\ - },{\ -+ .driver = "cirrus-vga",\ -+ .property = "vgamem_mb",\ -+ .value = OLD_VGA_MEM,\ -+ },{\ - .driver = "VGA",\ - .property = "mmio",\ - .value = "off",\ -@@ -371,6 +382,7 @@ static QEMUMachine pc_machine_v1_2 = { - DEFAULT_MACHINE_OPTIONS, - }; - -+ - #define PC_COMPAT_1_1 \ - PC_COMPAT_1_2,\ - {\ -@@ -384,19 +396,19 @@ static QEMUMachine pc_machine_v1_2 = { - },{\ - .driver = "VGA",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = OLD_VGA_MEM,\ - },{\ - .driver = "vmware-svga",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = OLD_VGA_MEM,\ - },{\ - .driver = "qxl-vga",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = OLD_VGA_MEM,\ - },{\ - .driver = "qxl",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = OLD_VGA_MEM,\ - },{\ - .driver = "virtio-blk-pci",\ - .property = "config-wce",\ diff --git a/0205-qxl-Add-rom_size-compat-property-fix-migration-from-.patch b/0205-qxl-Add-rom_size-compat-property-fix-migration-from-.patch deleted file mode 100644 index 746027f..0000000 --- a/0205-qxl-Add-rom_size-compat-property-fix-migration-from-.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 59d4955ec7fd78cabb8d2a2460d742580de180f1 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Tue, 19 Feb 2013 16:19:02 -0500 -Subject: [PATCH] qxl: Add rom_size compat property, fix migration from 1.2 - -Commit 038c1879a00153b14bce113315b693e8c2944fa9 changed the qxl rom -size to 8192, which fixes incoming migration from qemu 1.0. However -from qemu 1.2 and 1.3 had rom size 16384, so incoming migration -from those versions is now broken. - -Add a rom_size compat property. 1.2 and 1.3 get 16384, everything -else is 8192. - -This isn't actually fool proof, since rom_size can be dependent on -the version of spice qemu is built against: - -https://lists.gnu.org/archive/html/qemu-devel/2013-02/msg03154.html - -However these sizes match what native Fedora packages get, so it's -good enough for now. - -Signed-off-by: Cole Robinson ---- - hw/pc_piix.c | 16 ++++++++++++++++ - hw/qxl.c | 9 ++++----- - 2 files changed, 20 insertions(+), 5 deletions(-) - -diff --git a/hw/pc_piix.c b/hw/pc_piix.c -index e3f8e96..a1a6794 100644 ---- a/hw/pc_piix.c -+++ b/hw/pc_piix.c -@@ -317,6 +317,14 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { - .driver = "virtio-net-pci", \ - .property = "mq", \ - .value = "off", \ -+ },{ \ -+ .driver = "qxl", \ -+ .property = "rom_size", \ -+ .value = stringify(16384), \ -+ },{\ -+ .driver = "qxl-vga", \ -+ .property = "rom_size", \ -+ .value = stringify(16384), \ - } - - static QEMUMachine pc_machine_v1_3 = { -@@ -413,6 +421,14 @@ static QEMUMachine pc_machine_v1_2 = { - .driver = "virtio-blk-pci",\ - .property = "config-wce",\ - .value = "off",\ -+ },{ \ -+ .driver = "qxl", \ -+ .property = "rom_size", \ -+ .value = stringify(8192), \ -+ },{\ -+ .driver = "qxl-vga", \ -+ .property = "rom_size", \ -+ .value = stringify(8192), \ - } - - static QEMUMachine pc_machine_v1_1 = { -diff --git a/hw/qxl.c b/hw/qxl.c -index ca094e6..80bd92a 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -302,16 +302,14 @@ static inline uint32_t msb_mask(uint32_t val) - return mask; - } - --static ram_addr_t qxl_rom_size(void) -+static void check_qxl_rom_size(PCIQXLDevice *d) - { - uint32_t required_rom_size = sizeof(QXLRom) + sizeof(QXLModes) + - sizeof(qxl_modes); -- uint32_t rom_size = 8192; /* two pages */ - - required_rom_size = MAX(required_rom_size, TARGET_PAGE_SIZE); - required_rom_size = msb_mask(required_rom_size * 2 - 1); -- assert(required_rom_size <= rom_size); -- return rom_size; -+ assert(required_rom_size <= d->rom_size); - } - - static void init_qxl_rom(PCIQXLDevice *d) -@@ -1979,7 +1977,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) - pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev); - pci_set_byte(&config[PCI_INTERRUPT_PIN], 1); - -- qxl->rom_size = qxl_rom_size(); -+ check_qxl_rom_size(qxl); - memory_region_init_ram(&qxl->rom_bar, "qxl.vrom", qxl->rom_size); - vmstate_register_ram(&qxl->rom_bar, &qxl->pci.qdev); - init_qxl_rom(qxl); -@@ -2296,6 +2294,7 @@ static Property qxl_properties[] = { - DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1), - DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16), - DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024), -+ DEFINE_PROP_UINT32("rom_size", PCIQXLDevice, rom_size, 8192), - DEFINE_PROP_END_OF_LIST(), - }; - diff --git a/0206-rtl8139-flush-queued-packets-when-RxBufPtr-is-writte.patch b/0206-rtl8139-flush-queued-packets-when-RxBufPtr-is-writte.patch deleted file mode 100644 index feb4f26..0000000 --- a/0206-rtl8139-flush-queued-packets-when-RxBufPtr-is-writte.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e5cdc492ec39f777b0bd877ca794f3b2ccdcffec Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 22 May 2013 14:50:18 +0200 -Subject: [PATCH] rtl8139: flush queued packets when RxBufPtr is written - -Net queues support efficient "receive disable". For example, tap's file -descriptor will not be polled while its peer has receive disabled. This -saves CPU cycles for needlessly copying and then dropping packets which -the peer cannot receive. - -rtl8139 is missing the qemu_flush_queued_packets() call that wakes the -queue up when receive becomes possible again. - -As a result, the Windows 7 guest driver reaches a state where the -rtl8139 cannot receive packets. The driver has actually refilled the -receive buffer but we never resume reception. - -The bug can be reproduced by running a large FTP 'get' inside a Windows -7 guest: - - $ qemu -netdev tap,id=tap0,... - -device rtl8139,netdev=tap0 - -The Linux guest driver does not trigger the bug, probably due to a -different buffer management strategy. - -Reported-by: Oliver Francke -Signed-off-by: Stefan Hajnoczi -(cherry picked from commit 00b7ade807b5ce6779ddd86ce29c5521ec5c529a) ---- - hw/rtl8139.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/rtl8139.c b/hw/rtl8139.c -index d7716be..2c4d9bd 100644 ---- a/hw/rtl8139.c -+++ b/hw/rtl8139.c -@@ -2575,6 +2575,9 @@ static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val) - /* this value is off by 16 */ - s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize); - -+ /* more buffer space may be available so try to receive */ -+ qemu_flush_queued_packets(qemu_get_queue(s->nic)); -+ - DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n", - s->RxBufferSize, s->RxBufAddr, s->RxBufPtr); - } diff --git a/0207-spice-qemu-char-vmc_write-Don-t-write-more-bytes-the.patch b/0207-spice-qemu-char-vmc_write-Don-t-write-more-bytes-the.patch deleted file mode 100644 index c77113d..0000000 --- a/0207-spice-qemu-char-vmc_write-Don-t-write-more-bytes-the.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ad0343a9c903b79c6dd3ecdafb05a704c14514b9 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 5 Apr 2013 11:30:24 +0200 -Subject: [PATCH] spice-qemu-char: vmc_write: Don't write more bytes then we're - asked too - -This one took me eons to debug, but I've finally found it now, oh well. - -The usage of the MIN macro in this line: - last_out = MIN(len, qemu_chr_be_can_write(scd->chr)); - -Causes qemu_chr_be_can_write to be called *twice*, since the MIN macro -evaluates its arguments twice (bad MIN macro, bad!). And the result of -the call can change between the 2 calls since the guest may have consumed -some data from the virtio ringbuffer between the calls! - -When this happens it is possible for qemu_chr_be_can_write to return less -then len in the call made for the comparision, and then to return more then -len in the actual call for the return-value of MIN, after which we will end -up writing len data + some extra garbage, not good. - -This patch fixes this by only calling qemu_chr_be_can_write once. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann -(cherry picked from commit 75c439bc65c07d76f5e74c734ed5432bc6114a3b) ---- - spice-qemu-char.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/spice-qemu-char.c b/spice-qemu-char.c -index 5065240..82f3f77 100644 ---- a/spice-qemu-char.c -+++ b/spice-qemu-char.c -@@ -41,7 +41,8 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) - uint8_t* p = (uint8_t*)buf; - - while (len > 0) { -- last_out = MIN(len, qemu_chr_be_can_write(scd->chr)); -+ int can_write = qemu_chr_be_can_write(scd->chr); -+ last_out = MIN(len, can_write); - if (last_out <= 0) { - break; - } diff --git a/0208-configure-dtc-Probe-for-libfdt_env.h.patch b/0208-configure-dtc-Probe-for-libfdt_env.h.patch deleted file mode 100644 index 4812460..0000000 --- a/0208-configure-dtc-Probe-for-libfdt_env.h.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 70ef52a74f40710757ade876f1ae9ebeb9d9094c Mon Sep 17 00:00:00 2001 -From: Peter Crosthwaite -Date: Mon, 27 May 2013 14:20:57 +1000 -Subject: [PATCH] configure: dtc: Probe for libfdt_env.h - -Currently QEMU provides a local clone of the file libfdt_env.h in -/include. This file is supposed to come with the libfdt package and is -only needed for broken installs of libfdt. Now that we have submodule -dtc, just ignore these broken installs and prompt for the dtc submodule -install instead. QEMU's local libfdt_env.h is removed accordingly. - -Manifests as a bug when building QEMU with modern libfdt. The new -version of libfdt does not compile when QEMUs libfdt_env.h takes -precedence over the hosts. - -Signed-off-by: Peter Crosthwaite -Reviewed-by: Peter Maydell -Acked-by: David Gibson -Signed-off-by: Kim Phillips -Acked-by: Paolo Bonzini -Message-id: 9b6a3a52e3f46cfbc1ded9ab56385ec045e46705.1369628289.git.peter.crosthwaite@xilinx.com -Signed-off-by: Peter Maydell -(cherry picked from commit 96ce65457690561417ae8e6f0e85f3c6f135018b) ---- - configure | 2 ++ - include/libfdt_env.h | 36 ------------------------------------ - 2 files changed, 2 insertions(+), 36 deletions(-) - delete mode 100644 include/libfdt_env.h - -diff --git a/configure b/configure -index bc2870b..2996e1d 100755 ---- a/configure -+++ b/configure -@@ -2378,7 +2378,9 @@ fi - # fdt probe - if test "$fdt" != "no" ; then - fdt_libs="-lfdt" -+ # explicitly check for libfdt_env.h as it is missing in some stable installs - cat > $TMPC << EOF -+#include - int main(void) { return 0; } - EOF - if compile_prog "" "$fdt_libs" ; then -diff --git a/include/libfdt_env.h b/include/libfdt_env.h -deleted file mode 100644 -index 3667d4c..0000000 ---- a/include/libfdt_env.h -+++ /dev/null -@@ -1,36 +0,0 @@ --/* -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License, version 2, as -- * published by the Free Software Foundation. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, see . -- * -- * Copyright IBM Corp. 2008 -- * Authors: Hollis Blanchard -- * -- */ -- --#ifndef _LIBFDT_ENV_H --#define _LIBFDT_ENV_H -- --#include "qemu/bswap.h" -- --#ifdef HOST_WORDS_BIGENDIAN --#define fdt32_to_cpu(x) (x) --#define cpu_to_fdt32(x) (x) --#define fdt64_to_cpu(x) (x) --#define cpu_to_fdt64(x) (x) --#else --#define fdt32_to_cpu(x) bswap32(x) --#define cpu_to_fdt32(x) bswap32(x) --#define fdt64_to_cpu(x) bswap64(x) --#define cpu_to_fdt64(x) bswap64(x) --#endif -- --#endif /* _LIBFDT_ENV_H */ diff --git a/0209-Fix-usage-of-USB_DEV_FLAG_IS_HOST-flag.patch b/0209-Fix-usage-of-USB_DEV_FLAG_IS_HOST-flag.patch deleted file mode 100644 index 14bc1fd..0000000 --- a/0209-Fix-usage-of-USB_DEV_FLAG_IS_HOST-flag.patch +++ /dev/null @@ -1,29 +0,0 @@ -From e787bef7d85fdbb6a8d5b07bb84542e81d14cb8d Mon Sep 17 00:00:00 2001 -From: Michael Marineau -Date: Sun, 12 May 2013 19:19:37 -0400 -Subject: [PATCH] Fix usage of USB_DEV_FLAG_IS_HOST flag. - -USB_DEV_FLAG_IS_HOST is the bit number, not value. Booting with a -"Fitbit Base Station" USB dongle was triggering this assert. - -Signed-off-by: Michael Marineau -Cc: qemu-stable@nongnu.org -Signed-off-by: Gerd Hoffmann -(cherry picked from commit 756335292f2b46775992c314cc70b54480a46d26) ---- - hw/usb/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/usb/core.c b/hw/usb/core.c -index d057aab..67c41cd 100644 ---- a/hw/usb/core.c -+++ b/hw/usb/core.c -@@ -410,7 +410,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p) - assert(p->ep->type != USB_ENDPOINT_XFER_ISOC); - /* using async for interrupt packets breaks migration */ - assert(p->ep->type != USB_ENDPOINT_XFER_INT || -- (dev->flags & USB_DEV_FLAG_IS_HOST)); -+ (dev->flags & (1 << USB_DEV_FLAG_IS_HOST))); - usb_packet_set_state(p, USB_PACKET_ASYNC); - QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue); - } else if (p->status == USB_RET_ADD_TO_QUEUE) { diff --git a/0210-qxl-Fix-QXLRam-initialisation.patch b/0210-qxl-Fix-QXLRam-initialisation.patch deleted file mode 100644 index 4619d29..0000000 --- a/0210-qxl-Fix-QXLRam-initialisation.patch +++ /dev/null @@ -1,31 +0,0 @@ -From dadbf35f465f3423faa797a73c9a3caf5c6ab984 Mon Sep 17 00:00:00 2001 -From: Anthony PERARD -Date: Mon, 17 Jun 2013 17:38:26 +0100 -Subject: [PATCH] qxl: Fix QXLRam initialisation. - -The qxl driver expect NULL for QXLRam.memory_configs, but this is never -initialized. - -If memory is set to 0xc2c2.., it leads to a spice-critical error when -trying to start qxl. - -Signed-off-by: Anthony PERARD -Reviewed-by: Gerd Hoffmann -Signed-off-by: Michael Tokarev -(cherry picked from commit 329f97fc4ff4b533fcd2d8f4eab6c9c2568aed27) ---- - hw/qxl.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/qxl.c b/hw/qxl.c -index 80bd92a..5f52950 100644 ---- a/hw/qxl.c -+++ b/hw/qxl.c -@@ -381,6 +381,7 @@ static void init_qxl_ram(PCIQXLDevice *d) - d->ram->int_pending = cpu_to_le32(0); - d->ram->int_mask = cpu_to_le32(0); - d->ram->update_surface = 0; -+ d->ram->monitors_config = 0; - SPICE_RING_INIT(&d->ram->cmd_ring); - SPICE_RING_INIT(&d->ram->cursor_ring); - SPICE_RING_INIT(&d->ram->release_ring); diff --git a/0211-qemu-socket-Make-socket_optslist-public.patch b/0211-qemu-socket-Make-socket_optslist-public.patch deleted file mode 100644 index 4017ec9..0000000 --- a/0211-qemu-socket-Make-socket_optslist-public.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0d298cfe215b2e09debb62978eb77d7be4f37e1f Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Fri, 15 Mar 2013 17:14:24 +0100 -Subject: [PATCH] qemu-socket: Make socket_optslist public - -Allow other users to create the QemuOpts needed for inet_connect_opts(). - -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -(cherry picked from commit e62be8888a83aa0ab7f50eeb954deb2ec4e7201d) ---- - include/qemu/sockets.h | 2 ++ - util/qemu-sockets.c | 22 +++++++++++----------- - 2 files changed, 13 insertions(+), 11 deletions(-) - -diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h -index 42ca690..6eed34e 100644 ---- a/include/qemu/sockets.h -+++ b/include/qemu/sockets.h -@@ -31,6 +31,8 @@ int inet_aton(const char *cp, struct in_addr *ia); - #include "qapi/qmp/qerror.h" - #include "char/char.h" - -+extern QemuOptsList socket_optslist; -+ - /* misc helpers */ - int qemu_socket(int domain, int type, int protocol); - int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c -index cd54fb4..b32510a 100644 ---- a/util/qemu-sockets.c -+++ b/util/qemu-sockets.c -@@ -33,10 +33,10 @@ - - static const int on=1, off=0; - --/* used temporarely until all users are converted to QemuOpts */ --static QemuOptsList dummy_opts = { -- .name = "dummy", -- .head = QTAILQ_HEAD_INITIALIZER(dummy_opts.head), -+/* used temporarily until all users are converted to QemuOpts */ -+QemuOptsList socket_optslist = { -+ .name = "socket", -+ .head = QTAILQ_HEAD_INITIALIZER(socket_optslist.head), - .desc = { - { - .name = "path", -@@ -579,7 +579,7 @@ int inet_listen(const char *str, char *ostr, int olen, - - addr = inet_parse(str, errp); - if (addr != NULL) { -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - inet_addr_to_opts(opts, addr); - qapi_free_InetSocketAddress(addr); - sock = inet_listen_opts(opts, port_offset, errp); -@@ -652,7 +652,7 @@ int inet_nonblocking_connect(const char *str, - - addr = inet_parse(str, errp); - if (addr != NULL) { -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - inet_addr_to_opts(opts, addr); - qapi_free_InetSocketAddress(addr); - sock = inet_connect_opts(opts, errp, callback, opaque); -@@ -795,7 +795,7 @@ int unix_listen(const char *str, char *ostr, int olen, Error **errp) - char *path, *optstr; - int sock, len; - -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - - optstr = strchr(str, ','); - if (optstr) { -@@ -823,7 +823,7 @@ int unix_connect(const char *path, Error **errp) - QemuOpts *opts; - int sock; - -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - qemu_opt_set(opts, "path", path); - sock = unix_connect_opts(opts, errp, NULL, NULL); - qemu_opts_del(opts); -@@ -840,7 +840,7 @@ int unix_nonblocking_connect(const char *path, - - g_assert(callback != NULL); - -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - qemu_opt_set(opts, "path", path); - sock = unix_connect_opts(opts, errp, callback, opaque); - qemu_opts_del(opts); -@@ -891,7 +891,7 @@ int socket_connect(SocketAddress *addr, Error **errp, - QemuOpts *opts; - int fd; - -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - switch (addr->kind) { - case SOCKET_ADDRESS_KIND_INET: - inet_addr_to_opts(opts, addr->inet); -@@ -923,7 +923,7 @@ int socket_listen(SocketAddress *addr, Error **errp) - QemuOpts *opts; - int fd; - -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - switch (addr->kind) { - case SOCKET_ADDRESS_KIND_INET: - inet_addr_to_opts(opts, addr->inet); diff --git a/0212-libcacard-correct-T0-historical-bytes-size.patch b/0212-libcacard-correct-T0-historical-bytes-size.patch deleted file mode 100644 index ce89ec0..0000000 --- a/0212-libcacard-correct-T0-historical-bytes-size.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 82ba8008f0c6d7328872421e4d9d4f9868d74b11 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Sun, 2 Dec 2012 22:00:55 +0100 -Subject: [PATCH] libcacard: correct T0 historical bytes size -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The VCARD_ATR_PREFIX macro adds a prefix of 6 characters only. - -pcsc_scan was complaining before the patch: - -+ Historical bytes: 56 43 41 52 44 5F 4E 53 53 - ERROR! ATR is truncated: 2 byte(s) is/are missing - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit e2fd2115ce26049335d66ae0ae5e5c0ad06fb498) ---- - libcacard/vcardt.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libcacard/vcardt.h b/libcacard/vcardt.h -index d3e9522..538bdde 100644 ---- a/libcacard/vcardt.h -+++ b/libcacard/vcardt.h -@@ -26,7 +26,7 @@ typedef struct VCardEmulStruct VCardEmul; - #define MAX_CHANNEL 4 - - /* create an ATR with appropriate historical bytes */ --#define VCARD_ATR_PREFIX(size) 0x3b, 0x68+(size), 0x00, 0xff, \ -+#define VCARD_ATR_PREFIX(size) 0x3b, 0x66+(size), 0x00, 0xff, \ - 'V', 'C', 'A', 'R', 'D', '_' - - diff --git a/0213-ccid-card-emul-do-not-crash-if-backend-is-not-provid.patch b/0213-ccid-card-emul-do-not-crash-if-backend-is-not-provid.patch deleted file mode 100644 index 0574385..0000000 --- a/0213-ccid-card-emul-do-not-crash-if-backend-is-not-provid.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ab2662a8074e329e15d92ee5bdce741b84901c4a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 21 Nov 2012 14:16:08 +0100 -Subject: [PATCH] ccid-card-emul: do not crash if backend is not provided -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Program received signal SIGSEGV, Segmentation fault. -__strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp-sse42.S:164 -164 movdqu (%rsi), %xmm2 -(gdb) bt - at /home/elmarco/320g/src/qemu/hw/ccid-card-emulated.c:477 - at /home/elmarco/320g/src/qemu/hw/ccid-card-emulated.c:503 - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit d0ebd78890fba2ab458ec34763dae8566ccb1b72) ---- - hw/ccid-card-emulated.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c -index c8f8ba3..210433e 100644 ---- a/hw/ccid-card-emulated.c -+++ b/hw/ccid-card-emulated.c -@@ -473,6 +473,9 @@ static uint32_t parse_enumeration(char *str, - { - uint32_t ret = not_found_value; - -+ if (str == NULL) -+ return 0; -+ - while (table->name != NULL) { - if (strcmp(table->name, str) == 0) { - ret = table->value; diff --git a/0214-ccid-make-backend_enum_table-static-const-and-adjust.patch b/0214-ccid-make-backend_enum_table-static-const-and-adjust.patch deleted file mode 100644 index 45b99ac..0000000 --- a/0214-ccid-make-backend_enum_table-static-const-and-adjust.patch +++ /dev/null @@ -1,46 +0,0 @@ -From c05bf7d253830527dbb6f4280f50e805c188bb57 Mon Sep 17 00:00:00 2001 -From: Jim Meyering -Date: Mon, 21 May 2012 21:56:20 +0200 -Subject: [PATCH] ccid: make backend_enum_table "static const" and adjust users -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Jim Meyering -Reviewed-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit d18c7117467aa5fae95a7c6eaffcf50618197e79) ---- - hw/ccid-card-emulated.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c -index 210433e..cb9ef10 100644 ---- a/hw/ccid-card-emulated.c -+++ b/hw/ccid-card-emulated.c -@@ -462,14 +462,14 @@ typedef struct EnumTable { - uint32_t value; - } EnumTable; - --EnumTable backend_enum_table[] = { -+static const EnumTable backend_enum_table[] = { - {BACKEND_NSS_EMULATED_NAME, BACKEND_NSS_EMULATED}, - {BACKEND_CERTIFICATES_NAME, BACKEND_CERTIFICATES}, - {NULL, 0}, - }; - - static uint32_t parse_enumeration(char *str, -- EnumTable *table, uint32_t not_found_value) -+ const EnumTable *table, uint32_t not_found_value) - { - uint32_t ret = not_found_value; - -@@ -490,7 +490,7 @@ static int emulated_initfn(CCIDCardState *base) - { - EmulatedState *card = DO_UPCAST(EmulatedState, base, base); - VCardEmulError ret; -- EnumTable *ptable; -+ const EnumTable *ptable; - - QSIMPLEQ_INIT(&card->event_list); - QSIMPLEQ_INIT(&card->guest_apdu_list); diff --git a/0215-ccid-declare-DEFAULT_ATR-table-to-be-static-const.patch b/0215-ccid-declare-DEFAULT_ATR-table-to-be-static-const.patch deleted file mode 100644 index a0c8f96..0000000 --- a/0215-ccid-declare-DEFAULT_ATR-table-to-be-static-const.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f45224daee28b04543bf913e4d544c77ba9751a4 Mon Sep 17 00:00:00 2001 -From: Jim Meyering -Date: Mon, 21 May 2012 21:51:33 +0200 -Subject: [PATCH] ccid: declare DEFAULT_ATR table to be "static const" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Jim Meyering -Reviewed-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit da000a4867749434e03896a5072321771736352a) ---- - hw/ccid-card-passthru.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c -index 0dde761..62070db 100644 ---- a/hw/ccid-card-passthru.c -+++ b/hw/ccid-card-passthru.c -@@ -27,7 +27,7 @@ do { \ - #define D_VERBOSE 4 - - /* TODO: do we still need this? */ --uint8_t DEFAULT_ATR[] = { -+static const uint8_t DEFAULT_ATR[] = { - /* - * From some example somewhere - * 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28 diff --git a/0216-libcacard-use-system-config-directory-for-nss-db-on-.patch b/0216-libcacard-use-system-config-directory-for-nss-db-on-.patch deleted file mode 100644 index 444a737..0000000 --- a/0216-libcacard-use-system-config-directory-for-nss-db-on-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 55f9a7671661393885ed67a5fdbd54a2bf8fed48 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 27 Feb 2013 21:08:06 +0100 -Subject: [PATCH] libcacard: use system config directory for nss db on win32 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's a bit nicer to look for default database under -CSIDL_COMMON_APPDATA\pki\nss rather that /etc/pki/nss. - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit e2d9c5e769d59f2bca649b8286892d49bdcfc2b1) ---- - libcacard/vcard_emul_nss.c | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c -index df79476..21d4689 100644 ---- a/libcacard/vcard_emul_nss.c -+++ b/libcacard/vcard_emul_nss.c -@@ -893,7 +893,23 @@ vcard_emul_init(const VCardEmulOptions *options) - if (options->nss_db) { - rv = NSS_Init(options->nss_db); - } else { -- rv = NSS_Init("sql:/etc/pki/nssdb"); -+ gchar *path, *db; -+#ifndef _WIN32 -+ path = g_strdup("/etc/pki/nssdb"); -+#else -+ if (g_get_system_config_dirs() == NULL || -+ g_get_system_config_dirs()[0] == NULL) { -+ return VCARD_EMUL_FAIL; -+ } -+ -+ path = g_build_filename( -+ g_get_system_config_dirs()[0], "pki", "nssdb", NULL); -+#endif -+ db = g_strdup_printf("sql:%s", path); -+ -+ rv = NSS_Init(db); -+ g_free(db); -+ g_free(path); - } - if (rv != SECSuccess) { - return VCARD_EMUL_FAIL; diff --git a/0217-util-move-socket_init-to-osdep.c.patch b/0217-util-move-socket_init-to-osdep.c.patch deleted file mode 100644 index 3246bf2..0000000 --- a/0217-util-move-socket_init-to-osdep.c.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 9819cebc4010a996b466669022e78dfedd4f0b9f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Mon, 25 Feb 2013 23:31:11 +0100 -Subject: [PATCH] util: move socket_init() to osdep.c -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -vscclient needs to call socket_init() for portability. -Moving to osdep.c since it has no internal dependency. - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit d3bf825e59125bc6a0accec0dca119ea0155cb82) - -Conflicts: - util/qemu-sockets.c ---- - util/osdep.c | 23 +++++++++++++++++++++++ - util/qemu-sockets.c | 26 +------------------------- - 2 files changed, 24 insertions(+), 25 deletions(-) - -diff --git a/util/osdep.c b/util/osdep.c -index 5b51a03..3c1a0a3 100644 ---- a/util/osdep.c -+++ b/util/osdep.c -@@ -400,3 +400,26 @@ bool fips_get_state(void) - return fips_enabled; - } - -+#ifdef _WIN32 -+static void socket_cleanup(void) -+{ -+ WSACleanup(); -+} -+#endif -+ -+int socket_init(void) -+{ -+#ifdef _WIN32 -+ WSADATA Data; -+ int ret, err; -+ -+ ret = WSAStartup(MAKEWORD(2, 2), &Data); -+ if (ret != 0) { -+ err = WSAGetLastError(); -+ fprintf(stderr, "WSAStartup: %d\n", err); -+ return -1; -+ } -+ atexit(socket_cleanup); -+#endif -+ return 0; -+} -diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c -index b32510a..7909381 100644 ---- a/util/qemu-sockets.c -+++ b/util/qemu-sockets.c -@@ -618,7 +618,7 @@ int inet_connect(const char *str, Error **errp) - - addr = inet_parse(str, errp); - if (addr != NULL) { -- opts = qemu_opts_create_nofail(&dummy_opts); -+ opts = qemu_opts_create_nofail(&socket_optslist); - inet_addr_to_opts(opts, addr); - qapi_free_InetSocketAddress(addr); - sock = inet_connect_opts(opts, errp, NULL, NULL); -@@ -945,27 +945,3 @@ int socket_listen(SocketAddress *addr, Error **errp) - qemu_opts_del(opts); - return fd; - } -- --#ifdef _WIN32 --static void socket_cleanup(void) --{ -- WSACleanup(); --} --#endif -- --int socket_init(void) --{ --#ifdef _WIN32 -- WSADATA Data; -- int ret, err; -- -- ret = WSAStartup(MAKEWORD(2,2), &Data); -- if (ret != 0) { -- err = WSAGetLastError(); -- fprintf(stderr, "WSAStartup: %d\n", err); -- return -1; -- } -- atexit(socket_cleanup); --#endif -- return 0; --} diff --git a/0218-build-sys-must-link-with-fstack-protector.patch b/0218-build-sys-must-link-with-fstack-protector.patch deleted file mode 100644 index cc71dc1..0000000 --- a/0218-build-sys-must-link-with-fstack-protector.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 2772b3db795ff963a6dc9fade6e561b6e23dea9a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Mon, 25 Feb 2013 23:31:12 +0100 -Subject: [PATCH] build-sys: must link with -fstack-protector -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It is needed to give that flag to the linker as well, but latest -libtool 2.4.2 still swallows that argument, so let's pass it with -libtool -Wc argument. - -qemu-1.4.0/stubs/arch-query-cpu-def.c:6: undefined reference to `__stack_chk_guard' - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit 37746c5eacf309fa019ea0fa45f776c36c561457) - -Conflicts: - configure ---- - configure | 8 +++++++- - rules.mak | 1 + - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/configure b/configure -index 2996e1d..e8633c5 100755 ---- a/configure -+++ b/configure -@@ -1197,7 +1197,7 @@ fi - gcc_flags="-Wold-style-declaration -Wold-style-definition -Wtype-limits" - gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_flags" - gcc_flags="-Wmissing-include-dirs -Wempty-body -Wnested-externs $gcc_flags" --gcc_flags="-fstack-protector-all -Wendif-labels $gcc_flags" -+gcc_flags="-Wendif-labels $gcc_flags" - gcc_flags="-Wno-initializer-overrides $gcc_flags" - # Note that we do not add -Werror to gcc_flags here, because that would - # enable it for all configure tests. If a configure test failed due -@@ -1216,6 +1216,11 @@ for flag in $gcc_flags; do - fi - done - -+if compile_prog "-Werror -fstack-protector-all" "" ; then -+ QEMU_CFLAGS="$QEMU_CFLAGS -fstack-protector-all" -+ LIBTOOLFLAGS="$LIBTOOLFLAGS -Wc,-fstack-protector-all" -+fi -+ - # Workaround for http://gcc.gnu.org/PR55489. Happens with -fPIE/-fPIC and - # large functions that use global variables. The bug is in all releases of - # GCC, but it became particularly acute in 4.6.x and 4.7.x. It is fixed in -@@ -3832,6 +3837,7 @@ fi - echo "LDFLAGS=$LDFLAGS" >> $config_host_mak - echo "ARLIBS_BEGIN=$arlibs_begin" >> $config_host_mak - echo "ARLIBS_END=$arlibs_end" >> $config_host_mak -+echo "LIBTOOLFLAGS=$LIBTOOLFLAGS" >> $config_host_mak - echo "LIBS+=$LIBS" >> $config_host_mak - echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak - echo "EXESUF=$EXESUF" >> $config_host_mak -diff --git a/rules.mak b/rules.mak -index edc2552..36aba2d 100644 ---- a/rules.mak -+++ b/rules.mak -@@ -36,6 +36,7 @@ LINK = $(call quiet-command,\ - $(if $(filter %.lo %.la,$^),$(LIBTOOL) --mode=link --tag=CC \ - )$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ - $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(version-obj-y) \ -+ $(if $(filter %.lo %.la,$^),$(LIBTOOLFLAGS)) \ - $(LIBS),$(if $(filter %.lo %.la,$^),"lt LINK ", " LINK ")"$(TARGET_DIR)$@") - endif - diff --git a/0219-libcacard-fix-mingw64-cross-compilation.patch b/0219-libcacard-fix-mingw64-cross-compilation.patch deleted file mode 100644 index 50555ec..0000000 --- a/0219-libcacard-fix-mingw64-cross-compilation.patch +++ /dev/null @@ -1,54 +0,0 @@ -From c47df42d06e9bbc8bd7e7a40754f6245f4bea83f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Mon, 25 Feb 2013 23:31:13 +0100 -Subject: [PATCH] libcacard: fix mingw64 cross-compilation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Compile and link with version.lo - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit 5354e4d242175e067bb70732f694ae9322a81351) ---- - Makefile | 8 ++++++-- - rules.mak | 3 ++- - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/Makefile b/Makefile -index 0d9099a..751cf1d 100644 ---- a/Makefile -+++ b/Makefile -@@ -148,11 +148,15 @@ recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES) - - bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS) - --version.o: $(SRC_PATH)/version.rc config-host.h -+version.o: $(SRC_PATH)/version.rc config-host.h | version.lo - $(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@") -+version.lo: $(SRC_PATH)/version.rc config-host.h -+ $(call quiet-command,$(LIBTOOL) --mode=compile --tag=RC $(WINDRES) -I. -o $@ $<,"lt RC $(TARGET_DIR)$@") - - version-obj-$(CONFIG_WIN32) += version.o --Makefile: $(version-obj-y) -+version-lobj-$(CONFIG_WIN32) += $(if $(LIBTOOL),version.lo) -+Makefile: $(version-obj-y) $(version-lobj-y) -+ - - ###################################################################### - # Build libraries -diff --git a/rules.mak b/rules.mak -index 36aba2d..292a422 100644 ---- a/rules.mak -+++ b/rules.mak -@@ -35,7 +35,8 @@ LIBTOOL += $(if $(V),,--quiet) - LINK = $(call quiet-command,\ - $(if $(filter %.lo %.la,$^),$(LIBTOOL) --mode=link --tag=CC \ - )$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ -- $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(version-obj-y) \ -+ $(sort $(filter %.o, $1)) $(filter-out %.o, $1) \ -+ $(if $(filter %.lo %.la,$^),$(version-lobj-y),$(version-obj-y)) \ - $(if $(filter %.lo %.la,$^),$(LIBTOOLFLAGS)) \ - $(LIBS),$(if $(filter %.lo %.la,$^),"lt LINK ", " LINK ")"$(TARGET_DIR)$@") - endif diff --git a/0220-libcacard-split-vscclient-main-from-socket-reading.patch b/0220-libcacard-split-vscclient-main-from-socket-reading.patch deleted file mode 100644 index a44e447..0000000 --- a/0220-libcacard-split-vscclient-main-from-socket-reading.patch +++ /dev/null @@ -1,374 +0,0 @@ -From 6a7a90c34f62ffca270db3dbe3653f4eb2145c32 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Mon, 25 Feb 2013 23:31:14 +0100 -Subject: [PATCH] libcacard: split vscclient main() from socket reading -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit a50b831ae1fe039b7c22793f307e0b8afdf50589) ---- - libcacard/vscclient.c | 314 ++++++++++++++++++++++++++------------------------ - 1 file changed, 162 insertions(+), 152 deletions(-) - -diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c -index 9b744f2..5e00db3 100644 ---- a/libcacard/vscclient.c -+++ b/libcacard/vscclient.c -@@ -211,6 +211,166 @@ get_id_from_string(char *string, unsigned int default_id) - return id; - } - -+static int -+on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) -+{ -+ uint32_t *capabilities = (incoming->capabilities); -+ int num_capabilities = -+ 1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t)); -+ int i; -+ int rv; -+ pthread_t thread_id; -+ -+ incoming->version = ntohl(incoming->version); -+ if (incoming->version != VSCARD_VERSION) { -+ if (verbose > 0) { -+ printf("warning: host has version %d, we have %d\n", -+ verbose, VSCARD_VERSION); -+ } -+ } -+ if (incoming->magic != VSCARD_MAGIC) { -+ printf("unexpected magic: got %d, expected %d\n", -+ incoming->magic, VSCARD_MAGIC); -+ return -1; -+ } -+ for (i = 0 ; i < num_capabilities; ++i) { -+ capabilities[i] = ntohl(capabilities[i]); -+ } -+ /* Future: check capabilities */ -+ /* remove whatever reader might be left in qemu, -+ * in case of an unclean previous exit. */ -+ send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); -+ /* launch the event_thread. This will trigger reader adds for all the -+ * existing readers */ -+ rv = pthread_create(&thread_id, NULL, event_thread, NULL); -+ if (rv < 0) { -+ perror("pthread_create"); -+ return rv; -+ } -+ return 0; -+} -+ -+#define APDUBufSize 270 -+ -+static int -+do_socket_read(void) -+{ -+ int rv; -+ int dwSendLength; -+ int dwRecvLength; -+ uint8_t pbRecvBuffer[APDUBufSize]; -+ uint8_t pbSendBuffer[APDUBufSize]; -+ VReaderStatus reader_status; -+ VReader *reader = NULL; -+ VSCMsgHeader mhHeader; -+ VSCMsgError *error_msg; -+ -+ rv = read(sock, &mhHeader, sizeof(mhHeader)); -+ if (rv < sizeof(mhHeader)) { -+ /* Error */ -+ if (rv < 0) { -+ perror("header read error\n"); -+ } else { -+ fprintf(stderr, "header short read %d\n", rv); -+ } -+ return -1; -+ } -+ mhHeader.type = ntohl(mhHeader.type); -+ mhHeader.reader_id = ntohl(mhHeader.reader_id); -+ mhHeader.length = ntohl(mhHeader.length); -+ if (verbose) { -+ printf("Header: type=%d, reader_id=%u length=%d (0x%x)\n", -+ mhHeader.type, mhHeader.reader_id, mhHeader.length, -+ mhHeader.length); -+ } -+ switch (mhHeader.type) { -+ case VSC_APDU: -+ case VSC_Flush: -+ case VSC_Error: -+ case VSC_Init: -+ rv = read(sock, pbSendBuffer, mhHeader.length); -+ break; -+ default: -+ fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type); -+ return -1; -+ } -+ switch (mhHeader.type) { -+ case VSC_APDU: -+ if (rv < 0) { -+ /* Error */ -+ fprintf(stderr, "read error\n"); -+ close(sock); -+ return -1; -+ } -+ if (verbose) { -+ printf(" recv APDU: "); -+ print_byte_array(pbSendBuffer, mhHeader.length); -+ } -+ /* Transmit received APDU */ -+ dwSendLength = mhHeader.length; -+ dwRecvLength = sizeof(pbRecvBuffer); -+ reader = vreader_get_reader_by_id(mhHeader.reader_id); -+ reader_status = vreader_xfr_bytes(reader, -+ pbSendBuffer, dwSendLength, -+ pbRecvBuffer, &dwRecvLength); -+ if (reader_status == VREADER_OK) { -+ mhHeader.length = dwRecvLength; -+ if (verbose) { -+ printf(" send response: "); -+ print_byte_array(pbRecvBuffer, mhHeader.length); -+ } -+ send_msg(VSC_APDU, mhHeader.reader_id, -+ pbRecvBuffer, dwRecvLength); -+ } else { -+ rv = reader_status; /* warning: not meaningful */ -+ send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t)); -+ } -+ vreader_free(reader); -+ reader = NULL; /* we've freed it, don't use it by accident -+ again */ -+ break; -+ case VSC_Flush: -+ /* TODO: actually flush */ -+ send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); -+ break; -+ case VSC_Error: -+ error_msg = (VSCMsgError *) pbSendBuffer; -+ if (error_msg->code == VSC_SUCCESS) { -+ qemu_mutex_lock(&pending_reader_lock); -+ if (pending_reader) { -+ vreader_set_id(pending_reader, mhHeader.reader_id); -+ vreader_free(pending_reader); -+ pending_reader = NULL; -+ qemu_cond_signal(&pending_reader_condition); -+ } -+ qemu_mutex_unlock(&pending_reader_lock); -+ break; -+ } -+ printf("warning: qemu refused to add reader\n"); -+ if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) { -+ /* clear pending reader, qemu can't handle any more */ -+ qemu_mutex_lock(&pending_reader_lock); -+ if (pending_reader) { -+ pending_reader = NULL; -+ /* make sure the event loop doesn't hang */ -+ qemu_cond_signal(&pending_reader_condition); -+ } -+ qemu_mutex_unlock(&pending_reader_lock); -+ } -+ break; -+ case VSC_Init: -+ if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) { -+ return -1; -+ } -+ break; -+ default: -+ printf("Default\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ - static void - do_command(void) - { -@@ -339,8 +499,6 @@ do_command(void) - } - - --#define APDUBufSize 270 -- - /* just for ease of parsing command line arguments. */ - #define MAX_CERTS 100 - -@@ -385,44 +543,6 @@ connect_to_qemu( - return sock; - } - --static int on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) --{ -- uint32_t *capabilities = (incoming->capabilities); -- int num_capabilities = -- 1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t)); -- int i; -- int rv; -- pthread_t thread_id; -- -- incoming->version = ntohl(incoming->version); -- if (incoming->version != VSCARD_VERSION) { -- if (verbose > 0) { -- printf("warning: host has version %d, we have %d\n", -- verbose, VSCARD_VERSION); -- } -- } -- if (incoming->magic != VSCARD_MAGIC) { -- printf("unexpected magic: got %d, expected %d\n", -- incoming->magic, VSCARD_MAGIC); -- return -1; -- } -- for (i = 0 ; i < num_capabilities; ++i) { -- capabilities[i] = ntohl(capabilities[i]); -- } -- /* Future: check capabilities */ -- /* remove whatever reader might be left in qemu, -- * in case of an unclean previous exit. */ -- send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); -- /* launch the event_thread. This will trigger reader adds for all the -- * existing readers */ -- rv = pthread_create(&thread_id, NULL, event_thread, NULL); -- if (rv < 0) { -- perror("pthread_create"); -- return rv; -- } -- return 0; --} -- - int - main( - int argc, -@@ -431,21 +551,13 @@ main( - char *qemu_host; - char *qemu_port; - VSCMsgHeader mhHeader; -- VSCMsgError *error_msg; - -- int rv; -- int dwSendLength; -- int dwRecvLength; -- uint8_t pbRecvBuffer[APDUBufSize]; -- uint8_t pbSendBuffer[APDUBufSize]; -- VReaderStatus reader_status; -- VReader *reader = NULL; - VCardEmulOptions *command_line_options = NULL; - - char *cert_names[MAX_CERTS]; - char *emul_args = NULL; - int cert_count = 0; -- int c; -+ int c, rv; - - while ((c = getopt(argc, argv, "c:e:pd:")) != -1) { - switch (c) { -@@ -548,109 +660,7 @@ main( - if (!FD_ISSET(sock, &fds)) { - continue; - } -- -- rv = read(sock, &mhHeader, sizeof(mhHeader)); -- if (rv < sizeof(mhHeader)) { -- /* Error */ -- if (rv < 0) { -- perror("header read error\n"); -- } else { -- fprintf(stderr, "header short read %d\n", rv); -- } -- return 8; -- } -- mhHeader.type = ntohl(mhHeader.type); -- mhHeader.reader_id = ntohl(mhHeader.reader_id); -- mhHeader.length = ntohl(mhHeader.length); -- if (verbose) { -- printf("Header: type=%d, reader_id=%u length=%d (0x%x)\n", -- mhHeader.type, mhHeader.reader_id, mhHeader.length, -- mhHeader.length); -- } -- switch (mhHeader.type) { -- case VSC_APDU: -- case VSC_Flush: -- case VSC_Error: -- case VSC_Init: -- rv = read(sock, pbSendBuffer, mhHeader.length); -- break; -- default: -- fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type); -- return 0; -- } -- switch (mhHeader.type) { -- case VSC_APDU: -- if (rv < 0) { -- /* Error */ -- fprintf(stderr, "read error\n"); -- close(sock); -- return 8; -- } -- if (verbose) { -- printf(" recv APDU: "); -- print_byte_array(pbSendBuffer, mhHeader.length); -- } -- /* Transmit received APDU */ -- dwSendLength = mhHeader.length; -- dwRecvLength = sizeof(pbRecvBuffer); -- reader = vreader_get_reader_by_id(mhHeader.reader_id); -- reader_status = vreader_xfr_bytes(reader, -- pbSendBuffer, dwSendLength, -- pbRecvBuffer, &dwRecvLength); -- if (reader_status == VREADER_OK) { -- mhHeader.length = dwRecvLength; -- if (verbose) { -- printf(" send response: "); -- print_byte_array(pbRecvBuffer, mhHeader.length); -- } -- send_msg(VSC_APDU, mhHeader.reader_id, -- pbRecvBuffer, dwRecvLength); -- } else { -- rv = reader_status; /* warning: not meaningful */ -- send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t)); -- } -- vreader_free(reader); -- reader = NULL; /* we've freed it, don't use it by accident -- again */ -- break; -- case VSC_Flush: -- /* TODO: actually flush */ -- send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); -- break; -- case VSC_Error: -- error_msg = (VSCMsgError *) pbSendBuffer; -- if (error_msg->code == VSC_SUCCESS) { -- qemu_mutex_lock(&pending_reader_lock); -- if (pending_reader) { -- vreader_set_id(pending_reader, mhHeader.reader_id); -- vreader_free(pending_reader); -- pending_reader = NULL; -- qemu_cond_signal(&pending_reader_condition); -- } -- qemu_mutex_unlock(&pending_reader_lock); -- break; -- } -- printf("warning: qemu refused to add reader\n"); -- if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) { -- /* clear pending reader, qemu can't handle any more */ -- qemu_mutex_lock(&pending_reader_lock); -- if (pending_reader) { -- pending_reader = NULL; -- /* make sure the event loop doesn't hang */ -- qemu_cond_signal(&pending_reader_condition); -- } -- qemu_mutex_unlock(&pending_reader_lock); -- } -- break; -- case VSC_Init: -- if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) { -- return -1; -- } -- break; -- default: -- printf("Default\n"); -- return 0; -- } -+ rv = do_socket_read(); - } while (rv >= 0); - - return 0; diff --git a/0221-libcacard-vscclient-to-use-QemuThread-for-portabilit.patch b/0221-libcacard-vscclient-to-use-QemuThread-for-portabilit.patch deleted file mode 100644 index 2784a3e..0000000 --- a/0221-libcacard-vscclient-to-use-QemuThread-for-portabilit.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 30cbcaa34cbfa214b8680b83ad8d5da3b4ac0512 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Mon, 25 Feb 2013 23:31:15 +0100 -Subject: [PATCH] libcacard: vscclient to use QemuThread for portability -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit 930c8ad472ec00d40cfbf1e9b1395946bf0dd392) ---- - libcacard/vscclient.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c -index 5e00db3..5f47634 100644 ---- a/libcacard/vscclient.c -+++ b/libcacard/vscclient.c -@@ -218,8 +218,7 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) - int num_capabilities = - 1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t)); - int i; -- int rv; -- pthread_t thread_id; -+ QemuThread thread_id; - - incoming->version = ntohl(incoming->version); - if (incoming->version != VSCARD_VERSION) { -@@ -242,11 +241,7 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) - send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); - /* launch the event_thread. This will trigger reader adds for all the - * existing readers */ -- rv = pthread_create(&thread_id, NULL, event_thread, NULL); -- if (rv < 0) { -- perror("pthread_create"); -- return rv; -- } -+ qemu_thread_create(&thread_id, event_thread, NULL, 0); - return 0; - } - diff --git a/0222-libcacard-teach-vscclient-to-use-GMainLoop-for-porta.patch b/0222-libcacard-teach-vscclient-to-use-GMainLoop-for-porta.patch deleted file mode 100644 index 26e8db5..0000000 --- a/0222-libcacard-teach-vscclient-to-use-GMainLoop-for-porta.patch +++ /dev/null @@ -1,544 +0,0 @@ -From a27ea89383fee656bb9b9eacca03c233bd673ad2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Mon, 25 Feb 2013 23:31:16 +0100 -Subject: [PATCH] libcacard: teach vscclient to use GMainLoop for portability -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This version handles non-blocking sending and receiving from the -socket. - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit c9495ee9eb57786f5a60d4591bb186b23f6b6bef) ---- - libcacard/vscclient.c | 391 +++++++++++++++++++++++++++++++------------------- - 1 file changed, 246 insertions(+), 145 deletions(-) - -diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c -index 5f47634..ac23647 100644 ---- a/libcacard/vscclient.c -+++ b/libcacard/vscclient.c -@@ -10,7 +10,10 @@ - * See the COPYING.LIB file in the top-level directory. - */ - -+#ifndef _WIN32 - #include -+#endif -+#include - - #include "qemu-common.h" - #include "qemu/thread.h" -@@ -22,9 +25,7 @@ - #include "vcard_emul.h" - #include "vevent.h" - --int verbose; -- --int sock; -+static int verbose; - - static void - print_byte_array( -@@ -51,7 +52,47 @@ print_usage(void) { - vcard_emul_usage(); - } - --static QemuMutex write_lock; -+static GIOChannel *channel_socket; -+static GByteArray *socket_to_send; -+static QemuMutex socket_to_send_lock; -+static guint socket_tag; -+ -+static void -+update_socket_watch(gboolean out); -+ -+static gboolean -+do_socket_send(GIOChannel *source, -+ GIOCondition condition, -+ gpointer data) -+{ -+ gsize bw; -+ GError *err = NULL; -+ -+ g_return_val_if_fail(socket_to_send->len != 0, FALSE); -+ g_return_val_if_fail(condition & G_IO_OUT, FALSE); -+ -+ g_io_channel_write_chars(channel_socket, -+ (gchar *)socket_to_send->data, socket_to_send->len, &bw, &err); -+ if (err != NULL) { -+ g_error("Error while sending socket %s", err->message); -+ return FALSE; -+ } -+ g_byte_array_remove_range(socket_to_send, 0, bw); -+ -+ if (socket_to_send->len == 0) { -+ update_socket_watch(FALSE); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+static gboolean -+socket_prepare_sending(gpointer user_data) -+{ -+ update_socket_watch(TRUE); -+ -+ return FALSE; -+} - - static int - send_msg( -@@ -60,10 +101,9 @@ send_msg( - const void *msg, - unsigned int length - ) { -- int rv; - VSCMsgHeader mhHeader; - -- qemu_mutex_lock(&write_lock); -+ qemu_mutex_lock(&socket_to_send_lock); - - if (verbose > 10) { - printf("sending type=%d id=%u, len =%u (0x%x)\n", -@@ -73,23 +113,11 @@ send_msg( - mhHeader.type = htonl(type); - mhHeader.reader_id = 0; - mhHeader.length = htonl(length); -- rv = write(sock, &mhHeader, sizeof(mhHeader)); -- if (rv < 0) { -- /* Error */ -- fprintf(stderr, "write header error\n"); -- close(sock); -- qemu_mutex_unlock(&write_lock); -- return 16; -- } -- rv = write(sock, msg, length); -- if (rv < 0) { -- /* Error */ -- fprintf(stderr, "write error\n"); -- close(sock); -- qemu_mutex_unlock(&write_lock); -- return 16; -- } -- qemu_mutex_unlock(&write_lock); -+ g_byte_array_append(socket_to_send, (guint8 *)&mhHeader, sizeof(mhHeader)); -+ g_byte_array_append(socket_to_send, (guint8 *)msg, length); -+ g_idle_add(socket_prepare_sending, NULL); -+ -+ qemu_mutex_unlock(&socket_to_send_lock); - - return 0; - } -@@ -245,139 +273,203 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) - return 0; - } - -+ -+enum { -+ STATE_HEADER, -+ STATE_MESSAGE, -+}; -+ - #define APDUBufSize 270 - --static int --do_socket_read(void) -+static gboolean -+do_socket_read(GIOChannel *source, -+ GIOCondition condition, -+ gpointer data) - { - int rv; - int dwSendLength; - int dwRecvLength; - uint8_t pbRecvBuffer[APDUBufSize]; -- uint8_t pbSendBuffer[APDUBufSize]; -+ static uint8_t pbSendBuffer[APDUBufSize]; - VReaderStatus reader_status; - VReader *reader = NULL; -- VSCMsgHeader mhHeader; -+ static VSCMsgHeader mhHeader; - VSCMsgError *error_msg; -+ GError *err = NULL; - -- rv = read(sock, &mhHeader, sizeof(mhHeader)); -- if (rv < sizeof(mhHeader)) { -- /* Error */ -- if (rv < 0) { -- perror("header read error\n"); -- } else { -- fprintf(stderr, "header short read %d\n", rv); -- } -- return -1; -- } -- mhHeader.type = ntohl(mhHeader.type); -- mhHeader.reader_id = ntohl(mhHeader.reader_id); -- mhHeader.length = ntohl(mhHeader.length); -- if (verbose) { -- printf("Header: type=%d, reader_id=%u length=%d (0x%x)\n", -- mhHeader.type, mhHeader.reader_id, mhHeader.length, -- mhHeader.length); -- } -- switch (mhHeader.type) { -- case VSC_APDU: -- case VSC_Flush: -- case VSC_Error: -- case VSC_Init: -- rv = read(sock, pbSendBuffer, mhHeader.length); -- break; -- default: -- fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type); -- return -1; -+ static gchar *buf; -+ static gsize br, to_read; -+ static int state = STATE_HEADER; -+ -+ if (state == STATE_HEADER && to_read == 0) { -+ buf = (gchar *)&mhHeader; -+ to_read = sizeof(mhHeader); - } -- switch (mhHeader.type) { -- case VSC_APDU: -- if (rv < 0) { -- /* Error */ -- fprintf(stderr, "read error\n"); -- close(sock); -- return -1; -+ -+ if (to_read > 0) { -+ g_io_channel_read_chars(source, (gchar *)buf, to_read, &br, &err); -+ if (err != NULL) { -+ g_error("error while reading: %s", err->message); - } -+ buf += br; -+ to_read -= br; -+ if (to_read != 0) { -+ return TRUE; -+ } -+ } -+ -+ if (state == STATE_HEADER) { -+ mhHeader.type = ntohl(mhHeader.type); -+ mhHeader.reader_id = ntohl(mhHeader.reader_id); -+ mhHeader.length = ntohl(mhHeader.length); - if (verbose) { -- printf(" recv APDU: "); -- print_byte_array(pbSendBuffer, mhHeader.length); -+ printf("Header: type=%d, reader_id=%u length=%d (0x%x)\n", -+ mhHeader.type, mhHeader.reader_id, mhHeader.length, -+ mhHeader.length); - } -- /* Transmit received APDU */ -- dwSendLength = mhHeader.length; -- dwRecvLength = sizeof(pbRecvBuffer); -- reader = vreader_get_reader_by_id(mhHeader.reader_id); -- reader_status = vreader_xfr_bytes(reader, -- pbSendBuffer, dwSendLength, -- pbRecvBuffer, &dwRecvLength); -- if (reader_status == VREADER_OK) { -- mhHeader.length = dwRecvLength; -+ switch (mhHeader.type) { -+ case VSC_APDU: -+ case VSC_Flush: -+ case VSC_Error: -+ case VSC_Init: -+ buf = (gchar *)pbSendBuffer; -+ to_read = mhHeader.length; -+ state = STATE_MESSAGE; -+ return TRUE; -+ default: -+ fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type); -+ return FALSE; -+ } -+ } -+ -+ if (state == STATE_MESSAGE) { -+ switch (mhHeader.type) { -+ case VSC_APDU: - if (verbose) { -- printf(" send response: "); -- print_byte_array(pbRecvBuffer, mhHeader.length); -+ printf(" recv APDU: "); -+ print_byte_array(pbSendBuffer, mhHeader.length); - } -- send_msg(VSC_APDU, mhHeader.reader_id, -- pbRecvBuffer, dwRecvLength); -- } else { -- rv = reader_status; /* warning: not meaningful */ -- send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t)); -- } -- vreader_free(reader); -- reader = NULL; /* we've freed it, don't use it by accident -- again */ -- break; -- case VSC_Flush: -- /* TODO: actually flush */ -- send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); -- break; -- case VSC_Error: -- error_msg = (VSCMsgError *) pbSendBuffer; -- if (error_msg->code == VSC_SUCCESS) { -- qemu_mutex_lock(&pending_reader_lock); -- if (pending_reader) { -- vreader_set_id(pending_reader, mhHeader.reader_id); -- vreader_free(pending_reader); -- pending_reader = NULL; -- qemu_cond_signal(&pending_reader_condition); -+ /* Transmit received APDU */ -+ dwSendLength = mhHeader.length; -+ dwRecvLength = sizeof(pbRecvBuffer); -+ reader = vreader_get_reader_by_id(mhHeader.reader_id); -+ reader_status = vreader_xfr_bytes(reader, -+ pbSendBuffer, dwSendLength, -+ pbRecvBuffer, &dwRecvLength); -+ if (reader_status == VREADER_OK) { -+ mhHeader.length = dwRecvLength; -+ if (verbose) { -+ printf(" send response: "); -+ print_byte_array(pbRecvBuffer, mhHeader.length); -+ } -+ send_msg(VSC_APDU, mhHeader.reader_id, -+ pbRecvBuffer, dwRecvLength); -+ } else { -+ rv = reader_status; /* warning: not meaningful */ -+ send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t)); - } -- qemu_mutex_unlock(&pending_reader_lock); -+ vreader_free(reader); -+ reader = NULL; /* we've freed it, don't use it by accident -+ again */ - break; -- } -- printf("warning: qemu refused to add reader\n"); -- if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) { -- /* clear pending reader, qemu can't handle any more */ -- qemu_mutex_lock(&pending_reader_lock); -- if (pending_reader) { -- pending_reader = NULL; -- /* make sure the event loop doesn't hang */ -- qemu_cond_signal(&pending_reader_condition); -+ case VSC_Flush: -+ /* TODO: actually flush */ -+ send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); -+ break; -+ case VSC_Error: -+ error_msg = (VSCMsgError *) pbSendBuffer; -+ if (error_msg->code == VSC_SUCCESS) { -+ qemu_mutex_lock(&pending_reader_lock); -+ if (pending_reader) { -+ vreader_set_id(pending_reader, mhHeader.reader_id); -+ vreader_free(pending_reader); -+ pending_reader = NULL; -+ qemu_cond_signal(&pending_reader_condition); -+ } -+ qemu_mutex_unlock(&pending_reader_lock); -+ break; - } -- qemu_mutex_unlock(&pending_reader_lock); -+ printf("warning: qemu refused to add reader\n"); -+ if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) { -+ /* clear pending reader, qemu can't handle any more */ -+ qemu_mutex_lock(&pending_reader_lock); -+ if (pending_reader) { -+ pending_reader = NULL; -+ /* make sure the event loop doesn't hang */ -+ qemu_cond_signal(&pending_reader_condition); -+ } -+ qemu_mutex_unlock(&pending_reader_lock); -+ } -+ break; -+ case VSC_Init: -+ if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) { -+ return FALSE; -+ } -+ break; -+ default: -+ g_warn_if_reached(); -+ return FALSE; - } -- break; -- case VSC_Init: -- if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) { -- return -1; -+ -+ state = STATE_HEADER; -+ } -+ -+ -+ return TRUE; -+} -+ -+static gboolean -+do_socket(GIOChannel *source, -+ GIOCondition condition, -+ gpointer data) -+{ -+ /* not sure if two watches work well with a single win32 sources */ -+ if (condition & G_IO_OUT) { -+ if (!do_socket_send(source, condition, data)) { -+ return FALSE; - } -- break; -- default: -- printf("Default\n"); -- return -1; - } - -- return 0; -+ if (condition & G_IO_IN) { -+ if (!do_socket_read(source, condition, data)) { -+ return FALSE; -+ } -+ } -+ -+ return TRUE; - } - - static void --do_command(void) -+update_socket_watch(gboolean out) -+{ -+ if (socket_tag != 0) { -+ g_source_remove(socket_tag); -+ } -+ -+ socket_tag = g_io_add_watch(channel_socket, -+ G_IO_IN | (out ? G_IO_OUT : 0), do_socket, NULL); -+} -+ -+static gboolean -+do_command(GIOChannel *source, -+ GIOCondition condition, -+ gpointer data) - { -- char inbuf[255]; - char *string; - VCardEmulError error; - static unsigned int default_reader_id; - unsigned int reader_id; - VReader *reader = NULL; -+ GError *err = NULL; -+ -+ g_assert(condition & G_IO_IN); - - reader_id = default_reader_id; -- string = fgets(inbuf, sizeof(inbuf), stdin); -+ g_io_channel_read_line(source, &string, NULL, NULL, &err); -+ if (err != NULL) { -+ g_error("Error while reading command: %s", err->message); -+ } -+ - if (string != NULL) { - if (strncmp(string, "exit", 4) == 0) { - /* remove all the readers */ -@@ -491,6 +583,8 @@ do_command(void) - vreader_free(reader); - printf("> "); - fflush(stdout); -+ -+ return TRUE; - } - - -@@ -504,7 +598,7 @@ connect_to_qemu( - ) { - struct addrinfo hints; - struct addrinfo *server; -- int ret; -+ int ret, sock; - - sock = qemu_socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) { -@@ -543,6 +637,8 @@ main( - int argc, - char *argv[] - ) { -+ GMainLoop *loop; -+ GIOChannel *channel_stdin; - char *qemu_host; - char *qemu_port; - VSCMsgHeader mhHeader; -@@ -552,7 +648,10 @@ main( - char *cert_names[MAX_CERTS]; - char *emul_args = NULL; - int cert_count = 0; -- int c, rv; -+ int c, sock; -+ -+ if (socket_init() != 0) -+ return 1; - - while ((c = getopt(argc, argv, "c:e:pd:")) != -1) { - switch (c) { -@@ -618,15 +717,33 @@ main( - exit(5); - } - -- qemu_mutex_init(&write_lock); -+ socket_to_send = g_byte_array_new(); -+ qemu_mutex_init(&socket_to_send_lock); - qemu_mutex_init(&pending_reader_lock); - qemu_cond_init(&pending_reader_condition); - - vcard_emul_init(command_line_options); - -+ loop = g_main_loop_new(NULL, true); -+ - printf("> "); - fflush(stdout); - -+#ifdef _WIN32 -+ channel_stdin = g_io_channel_win32_new_fd(STDIN_FILENO); -+#else -+ channel_stdin = g_io_channel_unix_new(STDIN_FILENO); -+#endif -+ g_io_add_watch(channel_stdin, G_IO_IN, do_command, NULL); -+#ifdef _WIN32 -+ channel_socket = g_io_channel_win32_new_socket(sock); -+#else -+ channel_socket = g_io_channel_unix_new(sock); -+#endif -+ g_io_channel_set_encoding(channel_socket, NULL, NULL); -+ /* we buffer ourself for thread safety reasons */ -+ g_io_channel_set_buffered(channel_socket, FALSE); -+ - /* Send init message, Host responds (and then we send reader attachments) */ - VSCMsgInit init = { - .version = htonl(VSCARD_VERSION), -@@ -635,28 +752,12 @@ main( - }; - send_msg(VSC_Init, mhHeader.reader_id, &init, sizeof(init)); - -- do { -- fd_set fds; -- -- FD_ZERO(&fds); -- FD_SET(1, &fds); -- FD_SET(sock, &fds); -+ g_main_loop_run(loop); -+ g_main_loop_unref(loop); - -- /* waiting on input from the socket */ -- rv = select(sock+1, &fds, NULL, NULL, NULL); -- if (rv < 0) { -- /* handle error */ -- perror("select"); -- return 7; -- } -- if (FD_ISSET(1, &fds)) { -- do_command(); -- } -- if (!FD_ISSET(sock, &fds)) { -- continue; -- } -- rv = do_socket_read(); -- } while (rv >= 0); -+ g_io_channel_unref(channel_stdin); -+ g_io_channel_unref(channel_socket); -+ g_byte_array_unref(socket_to_send); - - return 0; - } diff --git a/0223-libcacard-remove-sql-prefix.patch b/0223-libcacard-remove-sql-prefix.patch deleted file mode 100644 index 96636bf..0000000 --- a/0223-libcacard-remove-sql-prefix.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0cb5cdc4badf4f3415425413986b91915b1fab52 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 20 Mar 2013 14:07:48 +0100 -Subject: [PATCH] libcacard: remove sql: prefix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -For some reason, with sql:/ prefix, the PKCS11 modules are not loaded. - -This patch goes on top of Alon smartcard series. - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit 667e0b4b6806d53e0b46e29a15d24427ef958c78) ---- - libcacard/vcard_emul_nss.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c -index 21d4689..6b1ca8a 100644 ---- a/libcacard/vcard_emul_nss.c -+++ b/libcacard/vcard_emul_nss.c -@@ -893,7 +893,7 @@ vcard_emul_init(const VCardEmulOptions *options) - if (options->nss_db) { - rv = NSS_Init(options->nss_db); - } else { -- gchar *path, *db; -+ gchar *path; - #ifndef _WIN32 - path = g_strdup("/etc/pki/nssdb"); - #else -@@ -905,10 +905,8 @@ vcard_emul_init(const VCardEmulOptions *options) - path = g_build_filename( - g_get_system_config_dirs()[0], "pki", "nssdb", NULL); - #endif -- db = g_strdup_printf("sql:%s", path); - -- rv = NSS_Init(db); -- g_free(db); -+ rv = NSS_Init(path); - g_free(path); - } - if (rv != SECSuccess) { diff --git a/0224-libcacard-remove-default-libcoolkey-loading.patch b/0224-libcacard-remove-default-libcoolkey-loading.patch deleted file mode 100644 index 5b5ca6a..0000000 --- a/0224-libcacard-remove-default-libcoolkey-loading.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 218d4160ff017861388f37feb02fa818d55d4eb3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 20 Mar 2013 14:07:49 +0100 -Subject: [PATCH] libcacard: remove default libcoolkey loading -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use only the modules defined in the NSS database. - -Signed-off-by: Marc-André Lureau -Reviewed-by: Alon Levy -(cherry picked from commit ad2181f2b612cd8bf0a790faa2a1b51559f7234b) ---- - libcacard/vcard_emul_nss.c | 17 +---------------- - 1 file changed, 1 insertion(+), 16 deletions(-) - -diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c -index 6b1ca8a..9ba80fb 100644 ---- a/libcacard/vcard_emul_nss.c -+++ b/libcacard/vcard_emul_nss.c -@@ -870,7 +870,7 @@ VCardEmulError - vcard_emul_init(const VCardEmulOptions *options) - { - SECStatus rv; -- PRBool ret, has_readers = PR_FALSE, need_coolkey_module; -+ PRBool ret, has_readers = PR_FALSE; - VReader *vreader; - VReaderEmul *vreader_emul; - SECMODListLock *module_lock; -@@ -983,30 +983,15 @@ vcard_emul_init(const VCardEmulOptions *options) - /* make sure we have some PKCS #11 module loaded */ - module_lock = SECMOD_GetDefaultModuleListLock(); - module_list = SECMOD_GetDefaultModuleList(); -- need_coolkey_module = !has_readers; - SECMOD_GetReadLock(module_lock); - for (mlp = module_list; mlp; mlp = mlp->next) { - SECMODModule *module = mlp->module; - if (module_has_removable_hw_slots(module)) { -- need_coolkey_module = PR_FALSE; - break; - } - } - SECMOD_ReleaseReadLock(module_lock); - -- if (need_coolkey_module) { -- SECMODModule *module; -- module = SECMOD_LoadUserModule( -- (char *)"library=libcoolkeypk11.so name=Coolkey", -- NULL, PR_FALSE); -- if (module == NULL) { -- return VCARD_EMUL_FAIL; -- } -- SECMOD_DestroyModule(module); /* free our reference, Module will still -- * be on the list. -- * until we destroy it */ -- } -- - /* now examine all the slots, finding which should be readers */ - /* We should control this with options. For now we mirror out any - * removable hardware slot */ diff --git a/0225-dev-smartcard-reader-white-space-fixes.patch b/0225-dev-smartcard-reader-white-space-fixes.patch deleted file mode 100644 index d91ef09..0000000 --- a/0225-dev-smartcard-reader-white-space-fixes.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 4407e349fde5a3ab43a0cad130ec66e6a31c4471 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 18:45:49 +0200 -Subject: [PATCH] dev-smartcard-reader: white space fixes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 4543d43c6181d90f86fb528430f250810dde03d5) ---- - hw/usb/dev-smartcard-reader.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index 979a473..24c84ce 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -471,6 +471,7 @@ static const USBDesc desc_ccid = { - static const uint8_t *ccid_card_get_atr(CCIDCardState *card, uint32_t *len) - { - CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); -+ - if (cc->get_atr) { - return cc->get_atr(card, len); - } -@@ -482,6 +483,7 @@ static void ccid_card_apdu_from_guest(CCIDCardState *card, - uint32_t len) - { - CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); -+ - if (cc->apdu_from_guest) { - cc->apdu_from_guest(card, apdu, len); - } -@@ -490,6 +492,7 @@ static void ccid_card_apdu_from_guest(CCIDCardState *card, - static int ccid_card_exitfn(CCIDCardState *card) - { - CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); -+ - if (cc->exitfn) { - return cc->exitfn(card); - } -@@ -499,6 +502,7 @@ static int ccid_card_exitfn(CCIDCardState *card) - static int ccid_card_initfn(CCIDCardState *card) - { - CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); -+ - if (cc->initfn) { - return cc->initfn(card); - } diff --git a/0226-dev-smartcard-reader-nicer-debug-messages.patch b/0226-dev-smartcard-reader-nicer-debug-messages.patch deleted file mode 100644 index 9934602..0000000 --- a/0226-dev-smartcard-reader-nicer-debug-messages.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 5220cd7238ea12e4fa361372706dc81ae0e6b54a Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 18:50:33 +0200 -Subject: [PATCH] dev-smartcard-reader: nicer debug messages -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 7e1ac5abe3fbbfee4ddfc2d9971a644bd787e055) ---- - hw/usb/dev-smartcard-reader.c | 69 +++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 63 insertions(+), 6 deletions(-) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index 24c84ce..173dcc9 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -639,13 +639,47 @@ static void ccid_handle_reset(USBDevice *dev) - ccid_reset(s); - } - -+static const char *ccid_control_to_str(USBCCIDState *s, int request) -+{ -+ switch (request) { -+ /* generic - should be factored out if there are other debugees */ -+ case DeviceOutRequest | USB_REQ_SET_ADDRESS: -+ return "(generic) set address"; -+ case DeviceRequest | USB_REQ_GET_DESCRIPTOR: -+ return "(generic) get descriptor"; -+ case DeviceRequest | USB_REQ_GET_CONFIGURATION: -+ return "(generic) get configuration"; -+ case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: -+ return "(generic) set configuration"; -+ case DeviceRequest | USB_REQ_GET_STATUS: -+ return "(generic) get status"; -+ case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: -+ return "(generic) clear feature"; -+ case DeviceOutRequest | USB_REQ_SET_FEATURE: -+ return "(generic) set_feature"; -+ case InterfaceRequest | USB_REQ_GET_INTERFACE: -+ return "(generic) get interface"; -+ case InterfaceOutRequest | USB_REQ_SET_INTERFACE: -+ return "(generic) set interface"; -+ /* class requests */ -+ case ClassInterfaceOutRequest | CCID_CONTROL_ABORT: -+ return "ABORT"; -+ case ClassInterfaceRequest | CCID_CONTROL_GET_CLOCK_FREQUENCIES: -+ return "GET_CLOCK_FREQUENCIES"; -+ case ClassInterfaceRequest | CCID_CONTROL_GET_DATA_RATES: -+ return "GET_DATA_RATES"; -+ } -+ return "unknown"; -+} -+ - static void ccid_handle_control(USBDevice *dev, USBPacket *p, int request, - int value, int index, int length, uint8_t *data) - { - USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); - int ret; - -- DPRINTF(s, 1, "got control %x, value %x\n", request, value); -+ DPRINTF(s, 1, "%s: got control %s (%x), value %x\n", __func__, -+ ccid_control_to_str(s, request), request, value); - ret = usb_desc_handle_control(dev, p, request, value, index, length, data); - if (ret >= 0) { - return; -@@ -695,7 +729,7 @@ static uint8_t ccid_calc_status(USBCCIDState *s) - * bmCommandStatus - */ - uint8_t ret = ccid_card_status(s) | (s->bmCommandStatus << 6); -- DPRINTF(s, D_VERBOSE, "status = %d\n", ret); -+ DPRINTF(s, D_VERBOSE, "%s: status = %d\n", __func__, ret); - return ret; - } - -@@ -756,7 +790,7 @@ static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq, - p->b.bStatus = ccid_calc_status(s); - p->b.bError = s->bError; - if (p->b.bError) { -- DPRINTF(s, D_VERBOSE, "error %d", p->b.bError); -+ DPRINTF(s, D_VERBOSE, "error %d\n", p->b.bError); - } - memcpy(p->abData, data, len); - ccid_reset_error_status(s); -@@ -873,6 +907,28 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv) - } - } - -+static const char *ccid_message_type_to_str(uint8_t type) -+{ -+ switch (type) { -+ case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn: return "IccPowerOn"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff: return "IccPowerOff"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus: return "GetSlotStatus"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock: return "XfrBlock"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters: return "GetParameters"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters: return "ResetParameters"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters: return "SetParameters"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_Escape: return "Escape"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_IccClock: return "IccClock"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU: return "T0APDU"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_Secure: return "Secure"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical: return "Mechanical"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_Abort: return "Abort"; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_SetDataRateAndClockFrequency: -+ return "SetDataRateAndClockFrequency"; -+ } -+ return "unknown"; -+} -+ - static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p) - { - CCID_Header *ccid_header; -@@ -895,13 +951,15 @@ static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p) - "%s: bad USB_TOKEN_OUT length, should be at least 10 bytes\n", - __func__); - } else { -- DPRINTF(s, D_MORE_INFO, "%s %x\n", __func__, ccid_header->bMessageType); -+ DPRINTF(s, D_MORE_INFO, "%s %x %s\n", __func__, -+ ccid_header->bMessageType, -+ ccid_message_type_to_str(ccid_header->bMessageType)); - switch (ccid_header->bMessageType) { - case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus: - ccid_write_slot_status(s, ccid_header); - break; - case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn: -- DPRINTF(s, 1, "PowerOn: %d\n", -+ DPRINTF(s, 1, "%s: PowerOn: %d\n", __func__, - ((CCID_IccPowerOn *)(ccid_header))->bPowerSelect); - s->powered = true; - if (!ccid_card_inserted(s)) { -@@ -911,7 +969,6 @@ static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p) - ccid_write_data_block_atr(s, ccid_header); - break; - case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff: -- DPRINTF(s, 1, "PowerOff\n"); - ccid_reset_error_status(s); - s->powered = false; - ccid_write_slot_status(s, ccid_header); diff --git a/0227-dev-smartcard-reader-remove-aborts-never-triggered-b.patch b/0227-dev-smartcard-reader-remove-aborts-never-triggered-b.patch deleted file mode 100644 index b5dcb7e..0000000 --- a/0227-dev-smartcard-reader-remove-aborts-never-triggered-b.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 3ea945e317cfda37503bccc6c0548f7bebdb5ba3 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 18:55:07 +0200 -Subject: [PATCH] dev-smartcard-reader: remove aborts (never triggered, but - just in case) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 47bf53af7507986fc473cb308324340448fd85e7) ---- - hw/usb/dev-smartcard-reader.c | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index 173dcc9..54ea536 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -796,6 +796,12 @@ static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq, - ccid_reset_error_status(s); - } - -+static void ccid_report_error_failed(USBCCIDState *s, uint8_t error) -+{ -+ s->bmCommandStatus = COMMAND_STATUS_FAILED; -+ s->bError = error; -+} -+ - static void ccid_write_data_block_answer(USBCCIDState *s, - const uint8_t *data, uint32_t len) - { -@@ -803,7 +809,9 @@ static void ccid_write_data_block_answer(USBCCIDState *s, - uint8_t slot; - - if (!ccid_has_pending_answers(s)) { -- abort(); -+ DPRINTF(s, D_WARN, "error: no pending answer to return to guest\n"); -+ ccid_report_error_failed(s, ERROR_ICC_MUTE); -+ return; - } - ccid_remove_pending_answer(s, &slot, &seq); - ccid_write_data_block(s, slot, seq, data, len); -@@ -857,12 +865,6 @@ static void ccid_reset_parameters(USBCCIDState *s) - memcpy(s->abProtocolDataStructure, abDefaultProtocolDataStructure, len); - } - --static void ccid_report_error_failed(USBCCIDState *s, uint8_t error) --{ -- s->bmCommandStatus = COMMAND_STATUS_FAILED; -- s->bError = error; --} -- - /* NOTE: only a single slot is supported (SLOT_0) */ - static void ccid_on_slot_change(USBCCIDState *s, bool full) - { -@@ -1129,7 +1131,9 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card, - s->bmCommandStatus = COMMAND_STATUS_NO_ERROR; - answer = ccid_peek_next_answer(s); - if (answer == NULL) { -- abort(); -+ DPRINTF(s, D_WARN, "%s: error: unexpected lack of answer\n", __func__); -+ ccid_report_error_failed(s, ERROR_HW_ERROR); -+ return; - } - DPRINTF(s, 1, "APDU returned to guest %d (answer seq %d, slot %d)\n", - len, answer->seq, answer->slot); diff --git a/0228-dev-smartcard-reader-support-windows-guest.patch b/0228-dev-smartcard-reader-support-windows-guest.patch deleted file mode 100644 index f523135..0000000 --- a/0228-dev-smartcard-reader-support-windows-guest.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 749942f6d5fdfed2d860169cf5271373e6a02868 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 21:40:53 +0200 -Subject: [PATCH] dev-smartcard-reader: support windows guest -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -By not advertising USB wakeup support (which we don't). - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit c5cd7c875608911ec74817d24cd12b825014ba19) ---- - hw/usb/dev-smartcard-reader.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index 54ea536..db5dd6d 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -359,11 +359,11 @@ static const uint8_t qemu_ccid_descriptor[] = { - * 20000 Short APDU level exchange with CCID - * 40000 Short and Extended APDU level exchange with CCID - * -- * + 100000 USB Wake up signaling supported on card -+ * 100000 USB Wake up signaling supported on card - * insertion and removal. Must set bit 5 in bmAttributes - * in Configuration descriptor if 100000 is set. - */ -- 0xfe, 0x04, 0x11, 0x00, -+ 0xfe, 0x04, 0x01, 0x00, - /* - * u32 dwMaxCCIDMessageLength; For extended APDU in - * [261 + 10 , 65544 + 10]. Otherwise the minimum is diff --git a/0229-dev-smartcard-reader-reuse-usb.h-definitions.patch b/0229-dev-smartcard-reader-reuse-usb.h-definitions.patch deleted file mode 100644 index 3290726..0000000 --- a/0229-dev-smartcard-reader-reuse-usb.h-definitions.patch +++ /dev/null @@ -1,62 +0,0 @@ -From cede7cafc7b0056c44446468463eabbc89d4da2c Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 5 Mar 2013 15:31:26 +0200 -Subject: [PATCH] dev-smartcard-reader: reuse usb.h definitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 693e47738d05463b2743b0a652412d33cf254977) ---- - hw/usb/dev-smartcard-reader.c | 16 +++++----------- - 1 file changed, 5 insertions(+), 11 deletions(-) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index db5dd6d..75f813c 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -68,12 +68,6 @@ do { \ - #define BULK_IN_BUF_SIZE 384 - #define BULK_IN_PENDING_NUM 8 - --#define InterfaceOutClass \ -- ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)<<8) -- --#define InterfaceInClass \ -- ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)<<8) -- - #define CCID_MAX_PACKET_SIZE 64 - - #define CCID_CONTROL_ABORT 0x1 -@@ -410,8 +404,8 @@ static const USBDescStrings desc_strings = { - static const USBDescIface desc_iface0 = { - .bInterfaceNumber = 0, - .bNumEndpoints = 3, -- .bInterfaceClass = 0x0b, -- .bInterfaceSubClass = 0x00, -+ .bInterfaceClass = USB_CLASS_CSCID, -+ .bInterfaceSubClass = USB_SUBCLASS_UNDEFINED, - .bInterfaceProtocol = 0x00, - .iInterface = STR_INTERFACE, - .ndesc = 1, -@@ -687,15 +681,15 @@ static void ccid_handle_control(USBDevice *dev, USBPacket *p, int request, - - switch (request) { - /* Class specific requests. */ -- case InterfaceOutClass | CCID_CONTROL_ABORT: -+ case ClassInterfaceOutRequest | CCID_CONTROL_ABORT: - DPRINTF(s, 1, "ccid_control abort UNIMPLEMENTED\n"); - p->status = USB_RET_STALL; - break; -- case InterfaceInClass | CCID_CONTROL_GET_CLOCK_FREQUENCIES: -+ case ClassInterfaceRequest | CCID_CONTROL_GET_CLOCK_FREQUENCIES: - DPRINTF(s, 1, "ccid_control get clock frequencies UNIMPLEMENTED\n"); - p->status = USB_RET_STALL; - break; -- case InterfaceInClass | CCID_CONTROL_GET_DATA_RATES: -+ case ClassInterfaceRequest | CCID_CONTROL_GET_DATA_RATES: - DPRINTF(s, 1, "ccid_control get data rates UNIMPLEMENTED\n"); - p->status = USB_RET_STALL; - break; diff --git a/0230-libcacard-change-default-ATR.patch b/0230-libcacard-change-default-ATR.patch deleted file mode 100644 index 3646e74..0000000 --- a/0230-libcacard-change-default-ATR.patch +++ /dev/null @@ -1,39 +0,0 @@ -From b6c0f55dee51c131fc2e4154aae30693b88b4595 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 5 Mar 2013 15:35:24 +0200 -Subject: [PATCH] libcacard: change default ATR -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit a26dfd95d33d650f9f9f93b6ee6f03be925db1a8) ---- - libcacard/vcardt.h | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/libcacard/vcardt.h b/libcacard/vcardt.h -index 538bdde..3b9a619 100644 ---- a/libcacard/vcardt.h -+++ b/libcacard/vcardt.h -@@ -26,9 +26,17 @@ typedef struct VCardEmulStruct VCardEmul; - #define MAX_CHANNEL 4 - - /* create an ATR with appropriate historical bytes */ --#define VCARD_ATR_PREFIX(size) 0x3b, 0x66+(size), 0x00, 0xff, \ -- 'V', 'C', 'A', 'R', 'D', '_' -+#define TS_DIRECT_CONVENTION 0x3b -+#define TA_PRESENT 0x10 -+#define TB_PRESENT 0x20 -+#define TC_PRESENT 0x40 -+#define TD_PRESENT 0x80 - -+#define VCARD_ATR_PREFIX(size) \ -+ TS_DIRECT_CONVENTION, \ -+ TD_PRESENT + (6 + size), \ -+ 0x00, \ -+ 'V', 'C', 'A', 'R', 'D', '_' - - typedef enum { - VCARD_DONE, diff --git a/0231-ccid-card-passthru-add-atr-check.patch b/0231-ccid-card-passthru-add-atr-check.patch deleted file mode 100644 index 7ab89aa..0000000 --- a/0231-ccid-card-passthru-add-atr-check.patch +++ /dev/null @@ -1,92 +0,0 @@ -From a447d4fc0ece3d1f0ae20c89ddf4b01d7afdb553 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 18:39:09 +0200 -Subject: [PATCH] ccid-card-passthru: add atr check -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 0e61400c1941aabc9f45d5ff961b57337c7caac6) ---- - hw/ccid-card-passthru.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c -index 62070db..7fecd10 100644 ---- a/hw/ccid-card-passthru.c -+++ b/hw/ccid-card-passthru.c -@@ -138,6 +138,59 @@ static void ccid_card_vscard_handle_init( - ccid_card_vscard_send_init(card); - } - -+static int check_atr(PassthruState *card, uint8_t *data, int len) -+{ -+ int historical_length, opt_bytes; -+ int td_count = 0; -+ int td; -+ -+ if (len < 2) { -+ return 0; -+ } -+ historical_length = data[1] & 0xf; -+ opt_bytes = 0; -+ if (data[0] != 0x3b && data[0] != 0x3f) { -+ DPRINTF(card, D_WARN, "atr's T0 is 0x%X, not in {0x3b, 0x3f}\n", -+ data[0]); -+ return 0; -+ } -+ td_count = 0; -+ td = data[1] >> 4; -+ while (td && td_count < 2 && opt_bytes + historical_length + 2 < len) { -+ td_count++; -+ if (td & 0x1) { -+ opt_bytes++; -+ } -+ if (td & 0x2) { -+ opt_bytes++; -+ } -+ if (td & 0x4) { -+ opt_bytes++; -+ } -+ if (td & 0x8) { -+ opt_bytes++; -+ td = data[opt_bytes + 2] >> 4; -+ } -+ } -+ if (len < 2 + historical_length + opt_bytes) { -+ DPRINTF(card, D_WARN, -+ "atr too short: len %d, but historical_len %d, T1 0x%X\n", -+ len, historical_length, data[1]); -+ return 0; -+ } -+ if (len > 2 + historical_length + opt_bytes) { -+ DPRINTF(card, D_WARN, -+ "atr too long: len %d, but hist/opt %d/%d, T1 0x%X\n", -+ len, historical_length, opt_bytes, data[1]); -+ /* let it through */ -+ } -+ DPRINTF(card, D_VERBOSE, -+ "atr passes check: %d total length, %d historical, %d optional\n", -+ len, historical_length, opt_bytes); -+ -+ return 1; -+} -+ - static void ccid_card_vscard_handle_message(PassthruState *card, - VSCMsgHeader *scr_msg_header) - { -@@ -152,6 +205,12 @@ static void ccid_card_vscard_handle_message(PassthruState *card, - VSC_GENERAL_ERROR); - break; - } -+ if (!check_atr(card, data, scr_msg_header->length)) { -+ error_report("ATR is inconsistent, ignoring"); -+ ccid_card_vscard_send_error(card, scr_msg_header->reader_id, -+ VSC_GENERAL_ERROR); -+ break; -+ } - memcpy(card->atr, data, scr_msg_header->length); - card->atr_length = scr_msg_header->length; - ccid_card_card_inserted(&card->base); diff --git a/0301-ccid-card-passthru-dev-smartcard-reader-add-debug-en.patch b/0301-ccid-card-passthru-dev-smartcard-reader-add-debug-en.patch deleted file mode 100644 index 5109058..0000000 --- a/0301-ccid-card-passthru-dev-smartcard-reader-add-debug-en.patch +++ /dev/null @@ -1,107 +0,0 @@ -From b22a9a5c4b0a3907cf00b04a12b84a5366d1fc8d Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 18:41:28 +0200 -Subject: [PATCH] ccid-card-passthru, dev-smartcard-reader: add debug - environment variables -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduces a new utility function: parse_debug_env to avoid code -duplication. - -This overrides whatever debug value is set on the corresponding devices -from the command line, and is meant to ease the usage with any -management stack. For libvirt you can set environment variables by -extending the dom namespace, i.e: - - - - - - - - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit b16352acf3105000e14f194b556e159d5d06cff9) - -Conflicts: - include/qemu-common.h ---- - hw/ccid-card-passthru.c | 2 ++ - hw/usb/dev-smartcard-reader.c | 1 + - include/qemu-common.h | 5 +++++ - util/cutils.c | 23 +++++++++++++++++++++++ - 4 files changed, 31 insertions(+) - -diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c -index 7fecd10..4026ccd 100644 ---- a/hw/ccid-card-passthru.c -+++ b/hw/ccid-card-passthru.c -@@ -353,6 +353,8 @@ static int passthru_initfn(CCIDCardState *base) - error_report("missing chardev"); - return -1; - } -+ card->debug = parse_debug_env("QEMU_CCID_PASSTHRU_DEBUG", D_VERBOSE, -+ card->debug); - assert(sizeof(DEFAULT_ATR) <= MAX_ATR_SIZE); - memcpy(card->atr, DEFAULT_ATR, sizeof(DEFAULT_ATR)); - card->atr_length = sizeof(DEFAULT_ATR); -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index 75f813c..09c2403 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -1260,6 +1260,7 @@ static int ccid_initfn(USBDevice *dev) - s->bulk_out_pos = 0; - ccid_reset_parameters(s); - ccid_reset(s); -+ s->debug = parse_debug_env("QEMU_CCID_DEBUG", D_VERBOSE, s->debug); - return 0; - } - -diff --git a/include/qemu-common.h b/include/qemu-common.h -index 80016ad..77d0980 100644 ---- a/include/qemu-common.h -+++ b/include/qemu-common.h -@@ -430,4 +430,9 @@ int64_t pow2floor(int64_t value); - int uleb128_encode_small(uint8_t *out, uint32_t n); - int uleb128_decode_small(const uint8_t *in, uint32_t *n); - -+/* -+ * helper to parse debug environment variables -+ */ -+int parse_debug_env(const char *name, int max, int initial); -+ - #endif -diff --git a/util/cutils.c b/util/cutils.c -index 1439da4..32e1f5b 100644 ---- a/util/cutils.c -+++ b/util/cutils.c -@@ -422,3 +422,26 @@ int uleb128_decode_small(const uint8_t *in, uint32_t *n) - return 2; - } - } -+ -+/* -+ * helper to parse debug environment variables -+ */ -+int parse_debug_env(const char *name, int max, int initial) -+{ -+ char *debug_env = getenv(name); -+ char *inv = NULL; -+ int debug; -+ -+ if (!debug_env) { -+ return initial; -+ } -+ debug = strtol(debug_env, &inv, 10); -+ if (inv == debug_env) { -+ return initial; -+ } -+ if (debug < 0 || debug > max) { -+ fprintf(stderr, "warning: %s not in [0, %d]", name, max); -+ return initial; -+ } -+ return debug; -+} diff --git a/0302-dev-smartcard-reader-define-structs-for-CCID_Paramet.patch b/0302-dev-smartcard-reader-define-structs-for-CCID_Paramet.patch deleted file mode 100644 index ec8caa0..0000000 --- a/0302-dev-smartcard-reader-define-structs-for-CCID_Paramet.patch +++ /dev/null @@ -1,158 +0,0 @@ -From cf593228aeb0a8be714d3bf5d83d3e0eef87ea76 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 18:57:45 +0200 -Subject: [PATCH] dev-smartcard-reader: define structs for CCID_Parameter - internals -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 4942d6c39477f441a106430ab11f85806b4532f5) ---- - hw/usb/dev-smartcard-reader.c | 74 +++++++++++++++++++++++++++---------------- - 1 file changed, 47 insertions(+), 27 deletions(-) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index 09c2403..f2cab09 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -189,10 +189,34 @@ typedef struct QEMU_PACKED CCID_SlotStatus { - uint8_t bClockStatus; - } CCID_SlotStatus; - -+typedef struct QEMU_PACKED CCID_T0ProtocolDataStructure { -+ uint8_t bmFindexDindex; -+ uint8_t bmTCCKST0; -+ uint8_t bGuardTimeT0; -+ uint8_t bWaitingIntegerT0; -+ uint8_t bClockStop; -+} CCID_T0ProtocolDataStructure; -+ -+typedef struct QEMU_PACKED CCID_T1ProtocolDataStructure { -+ uint8_t bmFindexDindex; -+ uint8_t bmTCCKST1; -+ uint8_t bGuardTimeT1; -+ uint8_t bWaitingIntegerT1; -+ uint8_t bClockStop; -+ uint8_t bIFSC; -+ uint8_t bNadValue; -+} CCID_T1ProtocolDataStructure; -+ -+typedef union CCID_ProtocolDataStructure { -+ CCID_T0ProtocolDataStructure t0; -+ CCID_T1ProtocolDataStructure t1; -+ uint8_t data[7]; /* must be = max(sizeof(t0), sizeof(t1)) */ -+} CCID_ProtocolDataStructure; -+ - typedef struct QEMU_PACKED CCID_Parameter { - CCID_BULK_IN b; - uint8_t bProtocolNum; -- uint8_t abProtocolDataStructure[0]; -+ CCID_ProtocolDataStructure abProtocolDataStructure; - } CCID_Parameter; - - typedef struct QEMU_PACKED CCID_DataBlock { -@@ -224,7 +248,7 @@ typedef struct QEMU_PACKED CCID_SetParameters { - CCID_Header hdr; - uint8_t bProtocolNum; - uint16_t abRFU; -- uint8_t abProtocolDataStructure[0]; -+ CCID_ProtocolDataStructure abProtocolDataStructure; - } CCID_SetParameters; - - typedef struct CCID_Notify_Slot_Change { -@@ -254,8 +278,6 @@ typedef struct CCIDBus { - BusState qbus; - } CCIDBus; - --#define MAX_PROTOCOL_SIZE 7 -- - /* - * powered - defaults to true, changed by PowerOn/PowerOff messages - */ -@@ -279,7 +301,7 @@ typedef struct USBCCIDState { - uint8_t bError; - uint8_t bmCommandStatus; - uint8_t bProtocolNum; -- uint8_t abProtocolDataStructure[MAX_PROTOCOL_SIZE]; -+ CCID_ProtocolDataStructure abProtocolDataStructure; - uint32_t ulProtocolDataStructureSize; - uint32_t state_vmstate; - uint32_t migration_target_ip; -@@ -765,7 +787,7 @@ static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv) - h->b.bStatus = ccid_calc_status(s); - h->b.bError = s->bError; - h->bProtocolNum = s->bProtocolNum; -- memcpy(h->abProtocolDataStructure, s->abProtocolDataStructure, len); -+ h->abProtocolDataStructure = s->abProtocolDataStructure; - ccid_reset_error_status(s); - } - -@@ -825,38 +847,36 @@ static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv) - static void ccid_set_parameters(USBCCIDState *s, CCID_Header *recv) - { - CCID_SetParameters *ph = (CCID_SetParameters *) recv; -- uint32_t len = 0; -- if ((ph->bProtocolNum & 3) == 0) { -- len = 5; -- } -- if ((ph->bProtocolNum & 3) == 1) { -- len = 7; -- } -- if (len == 0) { -- s->bmCommandStatus = COMMAND_STATUS_FAILED; -- s->bError = 7; /* Protocol invalid or not supported */ -+ uint32_t protocol_num = ph->bProtocolNum & 3; -+ -+ if (protocol_num != 0 && protocol_num != 1) { -+ ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED); - return; - } -- s->bProtocolNum = ph->bProtocolNum; -- memcpy(s->abProtocolDataStructure, ph->abProtocolDataStructure, len); -- s->ulProtocolDataStructureSize = len; -- DPRINTF(s, 1, "%s: using len %d\n", __func__, len); -+ s->bProtocolNum = protocol_num; -+ s->abProtocolDataStructure = ph->abProtocolDataStructure; - } - - /* - * must be 5 bytes for T=0, 7 bytes for T=1 - * See page 52 - */ --static const uint8_t abDefaultProtocolDataStructure[7] = { -- 0x77, 0x00, 0x00, 0x00, 0x00, 0xfe /*IFSC*/, 0x00 /*NAD*/ }; -+static const CCID_ProtocolDataStructure defaultProtocolDataStructure = { -+ .t1 = { -+ .bmFindexDindex = 0x77, -+ .bmTCCKST1 = 0x00, -+ .bGuardTimeT1 = 0x00, -+ .bWaitingIntegerT1 = 0x00, -+ .bClockStop = 0x00, -+ .bIFSC = 0xfe, -+ .bNadValue = 0x00, -+ } -+}; - - static void ccid_reset_parameters(USBCCIDState *s) - { -- uint32_t len = sizeof(abDefaultProtocolDataStructure); -- - s->bProtocolNum = 1; /* T=1 */ -- s->ulProtocolDataStructureSize = len; -- memcpy(s->abProtocolDataStructure, abDefaultProtocolDataStructure, len); -+ s->abProtocolDataStructure = defaultProtocolDataStructure; - } - - /* NOTE: only a single slot is supported (SLOT_0) */ -@@ -1345,7 +1365,7 @@ static VMStateDescription ccid_vmstate = { - VMSTATE_UINT8(bError, USBCCIDState), - VMSTATE_UINT8(bmCommandStatus, USBCCIDState), - VMSTATE_UINT8(bProtocolNum, USBCCIDState), -- VMSTATE_BUFFER(abProtocolDataStructure, USBCCIDState), -+ VMSTATE_BUFFER(abProtocolDataStructure.data, USBCCIDState), - VMSTATE_UINT32(ulProtocolDataStructureSize, USBCCIDState), - VMSTATE_STRUCT_ARRAY(bulk_in_pending, USBCCIDState, - BULK_IN_PENDING_NUM, 1, bulk_in_vmstate, BulkIn), diff --git a/0303-dev-smartcard-reader-change-default-protocol-to-T-0.patch b/0303-dev-smartcard-reader-change-default-protocol-to-T-0.patch deleted file mode 100644 index e6ebac4..0000000 --- a/0303-dev-smartcard-reader-change-default-protocol-to-T-0.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 4a70750aabe57e3a24d16fd1c82acc7f1c6f66f0 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Wed, 27 Mar 2013 10:14:15 +0200 -Subject: [PATCH] dev-smartcard-reader: change default protocol to T=0 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We don't support T=1 so we shouldn't advertise it by default. - -Two independent changes: -* Default ATR - sets T=0. This gets overwritten by the client provided ATR later. -* Class descriptor - changes dwAdvertise dwProtocols.PPPP to 0x1 and dwProtocols.RRRR=0 per spec. - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit d7d218ef02d87c637d20d64da8f575d434ff6f78) ---- - hw/usb/dev-smartcard-reader.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index f2cab09..e97dfcb 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -335,8 +335,8 @@ static const uint8_t qemu_ccid_descriptor[] = { - */ - 0x07, /* u8 bVoltageSupport; 01h - 5.0v, 02h - 3.0, 03 - 1.8 */ - -- 0x03, 0x00, /* u32 dwProtocols; RRRR PPPP. RRRR = 0000h.*/ -- 0x00, 0x00, /* PPPP: 0001h = Protocol T=0, 0002h = Protocol T=1 */ -+ 0x00, 0x00, /* u32 dwProtocols; RRRR PPPP. RRRR = 0000h.*/ -+ 0x01, 0x00, /* PPPP: 0001h = Protocol T=0, 0002h = Protocol T=1 */ - /* u32 dwDefaultClock; in kHZ (0x0fa0 is 4 MHz) */ - 0xa0, 0x0f, 0x00, 0x00, - /* u32 dwMaximumClock; */ -@@ -875,7 +875,7 @@ static const CCID_ProtocolDataStructure defaultProtocolDataStructure = { - - static void ccid_reset_parameters(USBCCIDState *s) - { -- s->bProtocolNum = 1; /* T=1 */ -+ s->bProtocolNum = 0; /* T=0 */ - s->abProtocolDataStructure = defaultProtocolDataStructure; - } - diff --git a/0304-dev-smartcard-reader-copy-atr-protocol-to-ccid-param.patch b/0304-dev-smartcard-reader-copy-atr-protocol-to-ccid-param.patch deleted file mode 100644 index 193f3a6..0000000 --- a/0304-dev-smartcard-reader-copy-atr-protocol-to-ccid-param.patch +++ /dev/null @@ -1,81 +0,0 @@ -From bdba89b1e2ff2a5d72847741b87b1bf03a17f008 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 18:58:29 +0200 -Subject: [PATCH] dev-smartcard-reader: copy atr protocol to ccid parameters -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds todos. - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 2f8f916b6d4482976bb5cf179f65aa2cfcd1aec9) ---- - hw/usb/dev-smartcard-reader.c | 45 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index e97dfcb..4e08f9b 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -833,14 +833,59 @@ static void ccid_write_data_block_answer(USBCCIDState *s, - ccid_write_data_block(s, slot, seq, data, len); - } - -+static uint8_t atr_get_protocol_num(const uint8_t *atr, uint32_t len) -+{ -+ int i; -+ -+ if (len < 2 || !(atr[1] & 0x80)) { -+ /* too short or TD1 not included */ -+ return 0; /* T=0, default */ -+ } -+ i = 1 + !!(atr[1] & 0x10) + !!(atr[1] & 0x20) + !!(atr[1] & 0x40); -+ i += !!(atr[1] & 0x80); -+ return atr[i] & 0x0f; -+} -+ - static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv) - { - const uint8_t *atr = NULL; - uint32_t len = 0; -+ uint8_t atr_protocol_num; -+ CCID_T0ProtocolDataStructure *t0 = &s->abProtocolDataStructure.t0; -+ CCID_T1ProtocolDataStructure *t1 = &s->abProtocolDataStructure.t1; - - if (s->card) { - atr = ccid_card_get_atr(s->card, &len); - } -+ atr_protocol_num = atr_get_protocol_num(atr, len); -+ DPRINTF(s, D_VERBOSE, "%s: atr contains protocol=%d\n", __func__, -+ atr_protocol_num); -+ /* set parameters from ATR - see spec page 109 */ -+ s->bProtocolNum = (atr_protocol_num <= 1 ? atr_protocol_num -+ : s->bProtocolNum); -+ switch (atr_protocol_num) { -+ case 0: -+ /* TODO: unimplemented ATR T0 parameters */ -+ t0->bmFindexDindex = 0; -+ t0->bmTCCKST0 = 0; -+ t0->bGuardTimeT0 = 0; -+ t0->bWaitingIntegerT0 = 0; -+ t0->bClockStop = 0; -+ break; -+ case 1: -+ /* TODO: unimplemented ATR T1 parameters */ -+ t1->bmFindexDindex = 0; -+ t1->bmTCCKST1 = 0; -+ t1->bGuardTimeT1 = 0; -+ t1->bWaitingIntegerT1 = 0; -+ t1->bClockStop = 0; -+ t1->bIFSC = 0; -+ t1->bNadValue = 0; -+ break; -+ default: -+ DPRINTF(s, D_WARN, "%s: error: unsupported ATR protocol %d\n", -+ __func__, atr_protocol_num); -+ } - ccid_write_data_block(s, recv->bSlot, recv->bSeq, atr, len); - } - diff --git a/0305-libcacard-vreader-add-debugging-messages-for-apdu.patch b/0305-libcacard-vreader-add-debugging-messages-for-apdu.patch deleted file mode 100644 index 991cca1..0000000 --- a/0305-libcacard-vreader-add-debugging-messages-for-apdu.patch +++ /dev/null @@ -1,166 +0,0 @@ -From c8149d68b2b487ac37f4e7d74b8611d377f47d82 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 5 Mar 2013 15:32:19 +0200 -Subject: [PATCH] libcacard/vreader: add debugging messages for apdu -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Using g_debug with log domain libcacard - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 7a6858962457c54be44715d6562504c765d9ea76) ---- - libcacard/cac.c | 7 ----- - libcacard/cac.h | 8 ++++++ - libcacard/vreader.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 85 insertions(+), 7 deletions(-) - -diff --git a/libcacard/cac.c b/libcacard/cac.c -index 927a4ca..5864539 100644 ---- a/libcacard/cac.c -+++ b/libcacard/cac.c -@@ -12,13 +12,6 @@ - #include "vcard_emul.h" - #include "card_7816.h" - --#define CAC_GET_PROPERTIES 0x56 --#define CAC_GET_ACR 0x4c --#define CAC_READ_BUFFER 0x52 --#define CAC_UPDATE_BUFFER 0x58 --#define CAC_SIGN_DECRYPT 0x42 --#define CAC_GET_CERTIFICATE 0x36 -- - /* private data for PKI applets */ - typedef struct CACPKIAppletDataStruct { - unsigned char *cert; -diff --git a/libcacard/cac.h b/libcacard/cac.h -index 15a61be..d24a2a8 100644 ---- a/libcacard/cac.h -+++ b/libcacard/cac.h -@@ -9,6 +9,14 @@ - #define CAC_H 1 - #include "vcard.h" - #include "vreader.h" -+ -+#define CAC_GET_PROPERTIES 0x56 -+#define CAC_GET_ACR 0x4c -+#define CAC_READ_BUFFER 0x52 -+#define CAC_UPDATE_BUFFER 0x58 -+#define CAC_SIGN_DECRYPT 0x42 -+#define CAC_GET_CERTIFICATE 0x36 -+ - /* - * Initialize the cac card. This is the only public function in this file. All - * the rest are connected through function pointers. -diff --git a/libcacard/vreader.c b/libcacard/vreader.c -index f3efc27..5793d73 100644 ---- a/libcacard/vreader.c -+++ b/libcacard/vreader.c -@@ -5,6 +5,12 @@ - * See the COPYING.LIB file in the top-level directory. - */ - -+#ifdef G_LOG_DOMAIN -+#undef G_LOG_DOMAIN -+#endif -+#define G_LOG_DOMAIN "libcacard" -+#include -+ - #include "qemu-common.h" - #include "qemu/thread.h" - -@@ -13,6 +19,9 @@ - #include "card_7816.h" - #include "vreader.h" - #include "vevent.h" -+#include "cac.h" /* just for debugging defines */ -+ -+#define LIBCACARD_LOG_DOMAIN "libcacard" - - struct VReaderStruct { - int reference_count; -@@ -24,6 +33,66 @@ struct VReaderStruct { - VReaderEmulFree reader_private_free; - }; - -+/* -+ * Debug helpers -+ */ -+ -+static const char * -+apdu_ins_to_string(int ins) -+{ -+ switch (ins) { -+ case VCARD7816_INS_MANAGE_CHANNEL: -+ return "manage channel"; -+ case VCARD7816_INS_EXTERNAL_AUTHENTICATE: -+ return "external authenticate"; -+ case VCARD7816_INS_GET_CHALLENGE: -+ return "get challenge"; -+ case VCARD7816_INS_INTERNAL_AUTHENTICATE: -+ return "internal authenticate"; -+ case VCARD7816_INS_ERASE_BINARY: -+ return "erase binary"; -+ case VCARD7816_INS_READ_BINARY: -+ return "read binary"; -+ case VCARD7816_INS_WRITE_BINARY: -+ return "write binary"; -+ case VCARD7816_INS_UPDATE_BINARY: -+ return "update binary"; -+ case VCARD7816_INS_READ_RECORD: -+ return "read record"; -+ case VCARD7816_INS_WRITE_RECORD: -+ return "write record"; -+ case VCARD7816_INS_UPDATE_RECORD: -+ return "update record"; -+ case VCARD7816_INS_APPEND_RECORD: -+ return "append record"; -+ case VCARD7816_INS_ENVELOPE: -+ return "envelope"; -+ case VCARD7816_INS_PUT_DATA: -+ return "put data"; -+ case VCARD7816_INS_GET_DATA: -+ return "get data"; -+ case VCARD7816_INS_SELECT_FILE: -+ return "select file"; -+ case VCARD7816_INS_VERIFY: -+ return "verify"; -+ case VCARD7816_INS_GET_RESPONSE: -+ return "get response"; -+ case CAC_GET_PROPERTIES: -+ return "get properties"; -+ case CAC_GET_ACR: -+ return "get acr"; -+ case CAC_READ_BUFFER: -+ return "read buffer"; -+ case CAC_UPDATE_BUFFER: -+ return "update buffer"; -+ case CAC_SIGN_DECRYPT: -+ return "sign decrypt"; -+ case CAC_GET_CERTIFICATE: -+ return "get certificate"; -+ } -+ return "unknown"; -+} -+ - /* manage locking */ - static inline void - vreader_lock(VReader *reader) -@@ -204,7 +273,15 @@ vreader_xfr_bytes(VReader *reader, - response = vcard_make_response(status); - card_status = VCARD_DONE; - } else { -+ g_debug("%s: CLS=0x%x,INS=0x%x,P1=0x%x,P2=0x%x,Lc=%d,Le=%d %s\n", -+ __func__, apdu->a_cla, apdu->a_ins, apdu->a_p1, apdu->a_p2, -+ apdu->a_Lc, apdu->a_Le, apdu_ins_to_string(apdu->a_ins)); - card_status = vcard_process_apdu(card, apdu, &response); -+ if (response) { -+ g_debug("%s: status=%d sw1=0x%x sw2=0x%x len=%d (total=%d)\n", -+ __func__, response->b_status, response->b_sw1, -+ response->b_sw2, response->b_len, response->b_total_len); -+ } - } - assert(card_status == VCARD_DONE); - if (card_status == VCARD_DONE) { diff --git a/0306-libcacard-move-atr-setting-from-macro-to-function.patch b/0306-libcacard-move-atr-setting-from-macro-to-function.patch deleted file mode 100644 index 931624c..0000000 --- a/0306-libcacard-move-atr-setting-from-macro-to-function.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 3cab527b3f9be5bbc8b8d3637ff0a8d1cddd6356 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 5 Mar 2013 16:27:43 +0200 -Subject: [PATCH] libcacard: move atr setting from macro to function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only because qemu's checkpatch complains about it. - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 0b6a16c1a47b622b1a692ab179013d9e30e9cf3b) ---- - Makefile.objs | 1 + - libcacard/vcard_emul_nss.c | 14 +++++++++++--- - libcacard/vcardt.c | 40 ++++++++++++++++++++++++++++++++++++++++ - libcacard/vcardt.h | 13 ------------- - libcacard/vcardt_internal.h | 6 ++++++ - 5 files changed, 58 insertions(+), 16 deletions(-) - create mode 100644 libcacard/vcardt.c - create mode 100644 libcacard/vcardt_internal.h - -diff --git a/Makefile.objs b/Makefile.objs -index 3884790..729be2b 100644 ---- a/Makefile.objs -+++ b/Makefile.objs -@@ -32,6 +32,7 @@ libcacard-y += libcacard/vcard.o libcacard/vreader.o - libcacard-y += libcacard/vcard_emul_nss.o - libcacard-y += libcacard/vcard_emul_type.o - libcacard-y += libcacard/card_7816.o -+libcacard-y += libcacard/vcardt.o - - ###################################################################### - # Target independent part of system emulation. The long term path is to -diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c -index 9ba80fb..1a3e568 100644 ---- a/libcacard/vcard_emul_nss.c -+++ b/libcacard/vcard_emul_nss.c -@@ -33,6 +33,9 @@ - #include "vreader.h" - #include "vevent.h" - -+#include "libcacard/vcardt_internal.h" -+ -+ - typedef enum { - VCardEmulUnknown = -1, - VCardEmulFalse = 0, -@@ -519,18 +522,23 @@ vcard_emul_reader_get_slot(VReader *vreader) - } - - /* -- * Card ATR's map to physical cards. VCARD_ATR_PREFIX will set appropriate -+ * Card ATR's map to physical cards. vcard_alloc_atr will set appropriate - * historical bytes for any software emulated card. The remaining bytes can be - * used to indicate the actual emulator - */ --static const unsigned char nss_atr[] = { VCARD_ATR_PREFIX(3), 'N', 'S', 'S' }; -+static unsigned char *nss_atr; -+static int nss_atr_len; - - void - vcard_emul_get_atr(VCard *card, unsigned char *atr, int *atr_len) - { -- int len = MIN(sizeof(nss_atr), *atr_len); -+ int len; - assert(atr != NULL); - -+ if (nss_atr == NULL) { -+ nss_atr = vcard_alloc_atr("NSS", &nss_atr_len); -+ } -+ len = MIN(nss_atr_len, *atr_len); - memcpy(atr, nss_atr, len); - *atr_len = len; - } -diff --git a/libcacard/vcardt.c b/libcacard/vcardt.c -new file mode 100644 -index 0000000..9ce4648 ---- /dev/null -+++ b/libcacard/vcardt.c -@@ -0,0 +1,40 @@ -+#include -+#include -+#include -+ -+#include "libcacard/vcardt.h" -+ -+#include "libcacard/vcardt_internal.h" -+ -+/* create an ATR with appropriate historical bytes */ -+#define ATR_TS_DIRECT_CONVENTION 0x3b -+#define ATR_TA_PRESENT 0x10 -+#define ATR_TB_PRESENT 0x20 -+#define ATR_TC_PRESENT 0x40 -+#define ATR_TD_PRESENT 0x80 -+ -+unsigned char *vcard_alloc_atr(const char *postfix, int *atr_len) -+{ -+ int postfix_len; -+ const char prefix[] = "VCARD_"; -+ const char default_postfix[] = "DEFAULT"; -+ const int prefix_len = sizeof(prefix) - 1; -+ int total_len; -+ unsigned char *atr; -+ -+ if (postfix == NULL) { -+ postfix = default_postfix; -+ } -+ postfix_len = strlen(postfix); -+ total_len = 3 + prefix_len + postfix_len; -+ atr = g_malloc(total_len); -+ atr[0] = ATR_TS_DIRECT_CONVENTION; -+ atr[1] = ATR_TD_PRESENT + prefix_len + postfix_len; -+ atr[2] = 0x00; -+ memcpy(&atr[3], prefix, prefix_len); -+ memcpy(&atr[3 + prefix_len], postfix, postfix_len); -+ if (atr_len) { -+ *atr_len = total_len; -+ } -+ return atr; -+} -diff --git a/libcacard/vcardt.h b/libcacard/vcardt.h -index 3b9a619..795e265 100644 ---- a/libcacard/vcardt.h -+++ b/libcacard/vcardt.h -@@ -25,19 +25,6 @@ typedef struct VCardEmulStruct VCardEmul; - - #define MAX_CHANNEL 4 - --/* create an ATR with appropriate historical bytes */ --#define TS_DIRECT_CONVENTION 0x3b --#define TA_PRESENT 0x10 --#define TB_PRESENT 0x20 --#define TC_PRESENT 0x40 --#define TD_PRESENT 0x80 -- --#define VCARD_ATR_PREFIX(size) \ -- TS_DIRECT_CONVENTION, \ -- TD_PRESENT + (6 + size), \ -- 0x00, \ -- 'V', 'C', 'A', 'R', 'D', '_' -- - typedef enum { - VCARD_DONE, - VCARD_NEXT, -diff --git a/libcacard/vcardt_internal.h b/libcacard/vcardt_internal.h -new file mode 100644 -index 0000000..e5c8d2d ---- /dev/null -+++ b/libcacard/vcardt_internal.h -@@ -0,0 +1,6 @@ -+#ifndef VCARDT_INTERNAL_H -+#define VCARDT_INTERNAL_H -+ -+unsigned char *vcard_alloc_atr(const char *postfix, int *atr_len); -+ -+#endif diff --git a/0307-dev-smartcard-reader-empty-implementation-for-Mechan.patch b/0307-dev-smartcard-reader-empty-implementation-for-Mechan.patch deleted file mode 100644 index c779dd3..0000000 --- a/0307-dev-smartcard-reader-empty-implementation-for-Mechan.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 6c11295ab78a3b421d94c64a88bec74676e0bc4f Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 5 Mar 2013 17:31:10 +0200 -Subject: [PATCH] dev-smartcard-reader: empty implementation for Mechanical - (fail correctly) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 58aeda15abb963196faaa4a0f23c5af45840f1b0) ---- - hw/usb/dev-smartcard-reader.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c -index 4e08f9b..a473b87 100644 ---- a/hw/usb/dev-smartcard-reader.c -+++ b/hw/usb/dev-smartcard-reader.c -@@ -1051,6 +1051,10 @@ static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p) - ccid_reset_error_status(s); - ccid_write_parameters(s, ccid_header); - break; -+ case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical: -+ ccid_report_error_failed(s, 0); -+ ccid_write_slot_status(s, ccid_header); -+ break; - default: - DPRINTF(s, 1, - "handle_data: ERROR: unhandled message type %Xh\n", diff --git a/0308-libcacard-cac-change-big-switch-functions-to-single-.patch b/0308-libcacard-cac-change-big-switch-functions-to-single-.patch deleted file mode 100644 index 3be3227..0000000 --- a/0308-libcacard-cac-change-big-switch-functions-to-single-.patch +++ /dev/null @@ -1,206 +0,0 @@ -From f90f2ac15af433ed36fce659bc2d40d533c3943f Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Mon, 4 Mar 2013 21:43:36 +0200 -Subject: [PATCH] libcacard/cac: change big switch functions to single return - point -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Alon Levy -Reviewed-by: Marc-André Lureau -(cherry picked from commit 57f97834efe0c208ffadc9d2959f3d3d55580e52) ---- - libcacard/cac.c | 73 ++++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 52 insertions(+), 21 deletions(-) - -diff --git a/libcacard/cac.c b/libcacard/cac.c -index 5864539..7a06b5a 100644 ---- a/libcacard/cac.c -+++ b/libcacard/cac.c -@@ -40,41 +40,51 @@ static VCardStatus - cac_common_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response) - { - int ef; -+ VCardStatus ret = VCARD_FAIL; - - switch (apdu->a_ins) { - case VCARD7816_INS_SELECT_FILE: - if (apdu->a_p1 != 0x02) { - /* let the 7816 code handle applet switches */ -- return VCARD_NEXT; -+ ret = VCARD_NEXT; -+ break; - } - /* handle file id setting */ - if (apdu->a_Lc != 2) { - *response = vcard_make_response( - VCARD7816_STATUS_ERROR_DATA_INVALID); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - } - /* CAC 1.0 only supports ef = 0 */ - ef = apdu->a_body[0] | (apdu->a_body[1] << 8); - if (ef != 0) { - *response = vcard_make_response( - VCARD7816_STATUS_ERROR_FILE_NOT_FOUND); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - } - *response = vcard_make_response(VCARD7816_STATUS_SUCCESS); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - case VCARD7816_INS_GET_RESPONSE: - case VCARD7816_INS_VERIFY: - /* let the 7816 code handle these */ -- return VCARD_NEXT; -+ ret = VCARD_NEXT; -+ break; - case CAC_GET_PROPERTIES: - case CAC_GET_ACR: - /* skip these for now, this will probably be needed */ - *response = vcard_make_response(VCARD7816_STATUS_ERROR_P1_P2_INCORRECT); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; -+ default: -+ *response = vcard_make_response( -+ VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED); -+ ret = VCARD_DONE; -+ break; - } -- *response = vcard_make_response( -- VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED); -- return VCARD_DONE; -+ return ret; - } - - /* -@@ -108,6 +118,7 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu, - int size, next; - unsigned char *sign_buffer; - vcard_7816_status_t status; -+ VCardStatus ret = VCARD_FAIL; - - applet_private = vcard_get_current_applet_private(card, apdu->a_channel); - assert(applet_private); -@@ -117,7 +128,8 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu, - case CAC_UPDATE_BUFFER: - *response = vcard_make_response( - VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - case CAC_GET_CERTIFICATE: - if ((apdu->a_p2 != 0) || (apdu->a_p1 != 0)) { - *response = vcard_make_response( -@@ -147,7 +159,8 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu, - *response = vcard_make_response( - VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE); - } -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - case CAC_SIGN_DECRYPT: - if (apdu->a_p2 != 0) { - *response = vcard_make_response( -@@ -164,7 +177,8 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu, - pki_applet->sign_buffer_len = 0; - *response = vcard_make_response( - VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - } - memcpy(sign_buffer+pki_applet->sign_buffer_len, apdu->a_body, size); - size += pki_applet->sign_buffer_len; -@@ -175,7 +189,8 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu, - pki_applet->sign_buffer = sign_buffer; - pki_applet->sign_buffer_len = size; - *response = vcard_make_response(VCARD7816_STATUS_SUCCESS); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - case 0x00: - /* we now have the whole buffer, do the operation, result will be - * in the sign_buffer */ -@@ -200,15 +215,20 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu, - g_free(sign_buffer); - pki_applet->sign_buffer = NULL; - pki_applet->sign_buffer_len = 0; -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - case CAC_READ_BUFFER: - /* new CAC call, go ahead and use the old version for now */ - /* TODO: implement */ - *response = vcard_make_response( - VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; -+ default: -+ ret = cac_common_process_apdu(card, apdu, response); -+ break; - } -- return cac_common_process_apdu(card, apdu, response); -+ return ret; - } - - -@@ -216,19 +236,26 @@ static VCardStatus - cac_applet_id_process_apdu(VCard *card, VCardAPDU *apdu, - VCardResponse **response) - { -+ VCardStatus ret = VCARD_FAIL; -+ - switch (apdu->a_ins) { - case CAC_UPDATE_BUFFER: - *response = vcard_make_response( - VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - case CAC_READ_BUFFER: - /* new CAC call, go ahead and use the old version for now */ - /* TODO: implement */ - *response = vcard_make_response( - VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; -+ default: -+ ret = cac_common_process_apdu(card, apdu, response); -+ break; - } -- return cac_common_process_apdu(card, apdu, response); -+ return ret; - } - - -@@ -240,16 +267,20 @@ static VCardStatus - cac_applet_container_process_apdu(VCard *card, VCardAPDU *apdu, - VCardResponse **response) - { -+ VCardStatus ret = VCARD_FAIL; -+ - switch (apdu->a_ins) { - case CAC_READ_BUFFER: - case CAC_UPDATE_BUFFER: - *response = vcard_make_response( - VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED); -- return VCARD_DONE; -+ ret = VCARD_DONE; -+ break; - default: -+ ret = cac_common_process_apdu(card, apdu, response); - break; - } -- return cac_common_process_apdu(card, apdu, response); -+ return ret; - } - - /* diff --git a/0309-libcacard-vscclient-fix-leakage-of-socket-on-error-p.patch b/0309-libcacard-vscclient-fix-leakage-of-socket-on-error-p.patch deleted file mode 100644 index d918935..0000000 --- a/0309-libcacard-vscclient-fix-leakage-of-socket-on-error-p.patch +++ /dev/null @@ -1,51 +0,0 @@ -From fb5d3b665f4a4c123ecf89c3d9da488f0f455d99 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Tue, 4 Jun 2013 16:23:37 -0400 -Subject: [PATCH] libcacard/vscclient: fix leakage of socket on error paths - -Spotted by Coverity. - -Signed-off-by: Alon Levy -Reviewed-by: Peter Maydell -Signed-off-by: Michael Tokarev -(cherry picked from commit 581fe784c3adf85dc167a47a4a60fd1245a98217) ---- - libcacard/vscclient.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c -index ac23647..5180d29 100644 ---- a/libcacard/vscclient.c -+++ b/libcacard/vscclient.c -@@ -618,18 +618,22 @@ connect_to_qemu( - if (ret != 0) { - /* Error */ - fprintf(stderr, "getaddrinfo failed\n"); -- return -1; -+ goto cleanup_socket; - } - - if (connect(sock, server->ai_addr, server->ai_addrlen) < 0) { - /* Error */ - fprintf(stderr, "Could not connect\n"); -- return -1; -+ goto cleanup_socket; - } - if (verbose) { - printf("Connected (sizeof Header=%zd)!\n", sizeof(VSCMsgHeader)); - } - return sock; -+ -+cleanup_socket: -+ closesocket(sock); -+ return -1; - } - - int -@@ -759,5 +763,6 @@ main( - g_io_channel_unref(channel_socket); - g_byte_array_unref(socket_to_send); - -+ closesocket(sock); - return 0; - } diff --git a/0310-libcacard-Fix-cppcheck-warning-and-remove-unneeded-c.patch b/0310-libcacard-Fix-cppcheck-warning-and-remove-unneeded-c.patch deleted file mode 100644 index 65d0306..0000000 --- a/0310-libcacard-Fix-cppcheck-warning-and-remove-unneeded-c.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 4b227c5279d96e767f5976d1e45d76ef485176a4 Mon Sep 17 00:00:00 2001 -From: Stefan Weil -Date: Sun, 16 Jun 2013 11:08:52 +0200 -Subject: [PATCH] libcacard: Fix cppcheck warning and remove unneeded code - -The local function vcard_emul_alloc_arrays always returned PR_TRUE. -Therefore cppcheck complained about code which handled the -non-existent PR_FALSE case. - -Remove the function's return value and the dead code. - -Signed-off-by: Stefan Weil -Signed-off-by: Michael Tokarev -(cherry picked from commit 48f0475f813dfa5ceb0e1f10c2ac3f28a8af583b) ---- - libcacard/vcard_emul_nss.c | 22 ++++++---------------- - 1 file changed, 6 insertions(+), 16 deletions(-) - -diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c -index 1a3e568..fb429b1 100644 ---- a/libcacard/vcard_emul_nss.c -+++ b/libcacard/vcard_emul_nss.c -@@ -90,17 +90,13 @@ static int nss_emul_init; - /* - * allocate the set of arrays for certs, cert_len, key - */ --static PRBool -+static void - vcard_emul_alloc_arrays(unsigned char ***certsp, int **cert_lenp, - VCardKey ***keysp, int cert_count) - { -- *certsp = NULL; -- *cert_lenp = NULL; -- *keysp = NULL; - *certsp = (unsigned char **)g_malloc(sizeof(unsigned char *)*cert_count); - *cert_lenp = (int *)g_malloc(sizeof(int)*cert_count); - *keysp = (VCardKey **)g_malloc(sizeof(VCardKey *)*cert_count); -- return PR_TRUE; - } - - /* -@@ -601,7 +597,6 @@ vcard_emul_mirror_card(VReader *vreader) - int *cert_len; - VCardKey **keys; - PK11SlotInfo *slot; -- PRBool ret; - VCard *card; - - slot = vcard_emul_reader_get_slot(vreader); -@@ -627,10 +622,7 @@ vcard_emul_mirror_card(VReader *vreader) - } - - /* allocate the arrays */ -- ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys, cert_count); -- if (ret == PR_FALSE) { -- return NULL; -- } -+ vcard_emul_alloc_arrays(&certs, &cert_len, &keys, cert_count); - - /* fill in the arrays */ - cert_count = 0; -@@ -878,7 +870,7 @@ VCardEmulError - vcard_emul_init(const VCardEmulOptions *options) - { - SECStatus rv; -- PRBool ret, has_readers = PR_FALSE; -+ PRBool has_readers = PR_FALSE; - VReader *vreader; - VReaderEmul *vreader_emul; - SECMODListLock *module_lock; -@@ -944,11 +936,9 @@ vcard_emul_init(const VCardEmulOptions *options) - vreader_add_reader(vreader); - cert_count = options->vreader[i].cert_count; - -- ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys, -- options->vreader[i].cert_count); -- if (ret == PR_FALSE) { -- continue; -- } -+ vcard_emul_alloc_arrays(&certs, &cert_len, &keys, -+ options->vreader[i].cert_count); -+ - cert_count = 0; - for (j = 0; j < options->vreader[i].cert_count; j++) { - /* we should have a better way of identifying certs than by diff --git a/0311-isapc-disable-kvmvapic.patch b/0311-isapc-disable-kvmvapic.patch deleted file mode 100644 index 910aafb..0000000 --- a/0311-isapc-disable-kvmvapic.patch +++ /dev/null @@ -1,34 +0,0 @@ -From df121e30406a1f892f383f86c76db936992354c2 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 13 Aug 2013 00:02:18 +0200 -Subject: [PATCH] isapc: disable kvmvapic - -vapic requires the VAPIC ROM to be mapped into RAM. This is not -possible without PAM hardware. This fixes a segmentation fault -running with -M isapc. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini - -(crobinso: s/kvmvapic/vapic/g) ---- - hw/pc_piix.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/hw/pc_piix.c b/hw/pc_piix.c -index a1a6794..9f3f93b 100644 ---- a/hw/pc_piix.c -+++ b/hw/pc_piix.c -@@ -689,7 +689,11 @@ static QEMUMachine isapc_machine = { - .property = "rom_only", - .value = stringify(1), - }, -- { /* end of list */ } -+ { -+ .driver = "apic-common", -+ .property = "vapic", -+ .value = "off", -+ }, - }, - DEFAULT_MACHINE_OPTIONS, - }; diff --git a/0315-scsi-avoid-assertion-failure-on-VERIFY-command.patch b/0315-scsi-avoid-assertion-failure-on-VERIFY-command.patch deleted file mode 100644 index 5f9fe30..0000000 --- a/0315-scsi-avoid-assertion-failure-on-VERIFY-command.patch +++ /dev/null @@ -1,63 +0,0 @@ -From eb8dbec969a5d32053e95f4c42c17c470d0558e7 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 8 Apr 2013 18:50:15 +0200 -Subject: [PATCH] scsi: avoid assertion failure on VERIFY command - -A verify command is not an actual read (we do not implement -compare mode) and thus does not have an AIOCB attached. Do -not crash in scsi_dma_complete. - -Signed-off-by: Paolo Bonzini -(cherry picked from commit ef8489d45927a6d35b214365e4b39ab311b48f2a) ---- - hw/scsi-disk.c | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - -diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c -index c9c983a..1d9cdd1 100644 ---- a/hw/scsi-disk.c -+++ b/hw/scsi-disk.c -@@ -242,14 +242,15 @@ done: - } - } - --static void scsi_dma_complete(void *opaque, int ret) -+static void scsi_dma_complete_noio(void *opaque, int ret) - { - SCSIDiskReq *r = (SCSIDiskReq *)opaque; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - -- assert(r->req.aiocb != NULL); -- r->req.aiocb = NULL; -- bdrv_acct_done(s->qdev.conf.bs, &r->acct); -+ if (r->req.aiocb != NULL) { -+ r->req.aiocb = NULL; -+ bdrv_acct_done(s->qdev.conf.bs, &r->acct); -+ } - if (r->req.io_canceled) { - goto done; - } -@@ -275,6 +276,14 @@ done: - } - } - -+static void scsi_dma_complete(void *opaque, int ret) -+{ -+ SCSIDiskReq *r = (SCSIDiskReq *)opaque; -+ -+ assert(r->req.aiocb != NULL); -+ scsi_dma_complete_noio(opaque, ret); -+} -+ - static void scsi_read_complete(void * opaque, int ret) - { - SCSIDiskReq *r = (SCSIDiskReq *)opaque; -@@ -494,7 +503,7 @@ static void scsi_write_data(SCSIRequest *req) - if (r->req.cmd.buf[0] == VERIFY_10 || r->req.cmd.buf[0] == VERIFY_12 || - r->req.cmd.buf[0] == VERIFY_16) { - if (r->req.sg) { -- scsi_dma_complete(r, 0); -+ scsi_dma_complete_noio(r, 0); - } else { - scsi_write_complete(r, 0); - } diff --git a/0316-target-ppc-Add-read-and-write-of-PPR-SPR.patch b/0316-target-ppc-Add-read-and-write-of-PPR-SPR.patch deleted file mode 100644 index 400bde4..0000000 --- a/0316-target-ppc-Add-read-and-write-of-PPR-SPR.patch +++ /dev/null @@ -1,30 +0,0 @@ -From f8028b0aa2318fc10df39c8dec1353b91e1597be Mon Sep 17 00:00:00 2001 -From: Anton Blanchard -Date: Wed, 1 May 2013 00:44:51 +0000 -Subject: [PATCH] target-ppc: Add read and write of PPR SPR - -Recent Linux kernels save and restore the PPR across exceptions -so we need to handle it. - -Signed-off-by: Anton Blanchard -Signed-off-by: Alexander Graf -(cherry picked from commit 04559d5210860ea5853db09c75ea8ff2f8843e16) ---- - target-ppc/translate_init.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c -index 88d9dfa..7e46fdc 100644 ---- a/target-ppc/translate_init.c -+++ b/target-ppc/translate_init.c -@@ -6738,6 +6738,10 @@ static void init_proc_POWER7 (CPUPPCState *env) - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); -+ spr_register(env, SPR_PPR, "PPR", -+ &spr_read_generic, &spr_write_generic, -+ &spr_read_generic, &spr_write_generic, -+ 0x00000000); - #if !defined(CONFIG_USER_ONLY) - env->slb_nr = 32; - #endif diff --git a/0317-qxl-fix-local-renderer.patch b/0317-qxl-fix-local-renderer.patch deleted file mode 100644 index f9a435c..0000000 --- a/0317-qxl-fix-local-renderer.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 95a8ab8e74cdf9140601b436edc9b7240ef2f8d4 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 5 Sep 2013 21:57:19 +0200 -Subject: [PATCH] qxl: fix local renderer - -The local spice renderer assumes the primary surface is located at the -start of the "ram" bar. This used to be a requirement in qxl hardware -revision 1. In revision 2+ this is relaxed. Nevertheless guest drivers -continued to use the traditional location, for historical and backward -compatibility reasons. The qxl kms driver doesn't though as it depends -on qxl revision 4+ anyway. - -Result is that local rendering is hosed for recent linux guests, you'll -get pixel garbage with non-spice ui (gtk, sdl, vnc) and when doing -screendumps. Fix that by doing a proper mapping of the guest-specified -memory location. - -https://bugzilla.redhat.com/show_bug.cgi?id=948717 - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit c58c7b959b93b864a27fd6b3646ee1465ab8832b) ---- - hw/qxl-render.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/hw/qxl-render.c b/hw/qxl-render.c -index 455fb91..fe21b18 100644 ---- a/hw/qxl-render.c -+++ b/hw/qxl-render.c -@@ -30,10 +30,6 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect) - if (is_buffer_shared(qxl->vga.ds->surface)) { - return; - } -- if (!qxl->guest_primary.data) { -- trace_qxl_render_blit_guest_primary_initialized(); -- qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram); -- } - trace_qxl_render_blit(qxl->guest_primary.qxl_stride, - rect->left, rect->right, rect->top, rect->bottom); - src = qxl->guest_primary.data; -@@ -102,7 +98,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) - - if (qxl->guest_primary.resized) { - qxl->guest_primary.resized = 0; -- qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram); -+ qxl->guest_primary.data = qxl_phys2virt(qxl, -+ qxl->guest_primary.surface.mem, -+ MEMSLOT_GROUP_GUEST); -+ if (!qxl->guest_primary.data) { -+ return; -+ } - qxl_set_rect_to_surface(qxl, &qxl->dirty[0]); - qxl->num_dirty_rects = 1; - trace_qxl_render_guest_primary_resized( -@@ -127,6 +128,10 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) - } - dpy_gfx_resize(vga->ds); - } -+ -+ if (!qxl->guest_primary.data) { -+ return; -+ } - for (i = 0; i < qxl->num_dirty_rects; i++) { - if (qemu_spice_rect_is_empty(qxl->dirty+i)) { - break; diff --git a/0318-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch b/0318-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch deleted file mode 100644 index c8b3b94..0000000 --- a/0318-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch +++ /dev/null @@ -1,155 +0,0 @@ -From e2fbed46dae80551daf1b8269cab5f6b586bd0d7 Mon Sep 17 00:00:00 2001 -From: Asias He -Date: Fri, 13 Sep 2013 14:56:55 +0800 -Subject: [PATCH] scsi: Allocate SCSITargetReq r->buf dynamically - -BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1007330 -Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=6282465 - -This is the backport of the following commit. The patch is not -sent public since it is a embargoed bug. - - r->buf is hardcoded to 2056 which is (256 + 1) * 8, allowing 256 luns at - most. If more than 256 luns are specified by user, we have buffer - overflow in scsi_target_emulate_report_luns. - - To fix, we allocate the buffer dynamically. - - Signed-off-by: Asias He - -Signed-off-by: Asias He -Signed-off-by: Paolo Bonzini - -*s/&r->buf/r->buf/ due to type change - -Signed-off-by: Michael Roth -(cherry picked from commit fdcbe7d587a64dec0db0d3c9a3b230c39efbfeef) ---- - hw/scsi-bus.c | 44 +++++++++++++++++++++++++++++++++----------- - hw/scsi.h | 2 ++ - 2 files changed, 35 insertions(+), 11 deletions(-) - -diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c -index 01e1dec..54c9596 100644 ---- a/hw/scsi-bus.c -+++ b/hw/scsi-bus.c -@@ -11,6 +11,8 @@ static char *scsibus_get_dev_path(DeviceState *dev); - static char *scsibus_get_fw_dev_path(DeviceState *dev); - static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf); - static void scsi_req_dequeue(SCSIRequest *req); -+static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len); -+static void scsi_target_free_buf(SCSIRequest *req); - - static Property scsi_props[] = { - DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), -@@ -304,7 +306,8 @@ typedef struct SCSITargetReq SCSITargetReq; - struct SCSITargetReq { - SCSIRequest req; - int len; -- uint8_t buf[2056]; -+ uint8_t *buf; -+ int buf_len; - }; - - static void store_lun(uint8_t *outbuf, int lun) -@@ -348,14 +351,12 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) - if (!found_lun0) { - n += 8; - } -- len = MIN(n + 8, r->req.cmd.xfer & ~7); -- if (len > sizeof(r->buf)) { -- /* TODO: > 256 LUNs? */ -- return false; -- } - -+ scsi_target_alloc_buf(&r->req, n + 8); -+ -+ len = MIN(n + 8, r->req.cmd.xfer & ~7); - memset(r->buf, 0, len); -- stl_be_p(&r->buf, n); -+ stl_be_p(r->buf, n); - i = found_lun0 ? 8 : 16; - QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) { - DeviceState *qdev = kid->child; -@@ -374,6 +375,9 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) - static bool scsi_target_emulate_inquiry(SCSITargetReq *r) - { - assert(r->req.dev->lun != r->req.lun); -+ -+ scsi_target_alloc_buf(&r->req, SCSI_INQUIRY_LEN); -+ - if (r->req.cmd.buf[1] & 0x2) { - /* Command support data - optional, not implemented */ - return false; -@@ -398,7 +402,7 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r) - return false; - } - /* done with EVPD */ -- assert(r->len < sizeof(r->buf)); -+ assert(r->len < r->buf_len); - r->len = MIN(r->req.cmd.xfer, r->len); - return true; - } -@@ -442,8 +446,8 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf) - } - break; - case REQUEST_SENSE: -- r->len = scsi_device_get_sense(r->req.dev, r->buf, -- MIN(req->cmd.xfer, sizeof r->buf), -+ scsi_target_alloc_buf(&r->req, SCSI_SENSE_LEN); -+ r->len = scsi_device_get_sense(r->req.dev, r->buf, r->buf_len, - (req->cmd.buf[1] & 1) == 0); - if (r->req.dev->sense_is_ua) { - scsi_device_unit_attention_reported(req->dev); -@@ -488,11 +492,29 @@ static uint8_t *scsi_target_get_buf(SCSIRequest *req) - return r->buf; - } - -+static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len) -+{ -+ SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req); -+ -+ r->buf = g_malloc(len); -+ r->buf_len = len; -+ -+ return r->buf; -+} -+ -+static void scsi_target_free_buf(SCSIRequest *req) -+{ -+ SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req); -+ -+ g_free(r->buf); -+} -+ - static const struct SCSIReqOps reqops_target_command = { - .size = sizeof(SCSITargetReq), - .send_command = scsi_target_send_command, - .read_data = scsi_target_read_data, - .get_buf = scsi_target_get_buf, -+ .free_req = scsi_target_free_buf, - }; - - -@@ -1348,7 +1370,7 @@ int scsi_build_sense(uint8_t *in_buf, int in_len, - buf[7] = 10; - buf[12] = sense.asc; - buf[13] = sense.ascq; -- return MIN(len, 18); -+ return MIN(len, SCSI_SENSE_LEN); - } else { - /* Return descriptor format sense buffer */ - buf[0] = 0x72; -diff --git a/hw/scsi.h b/hw/scsi.h -index a5b5b2e..d6028bf 100644 ---- a/hw/scsi.h -+++ b/hw/scsi.h -@@ -9,6 +9,8 @@ - #define MAX_SCSI_DEVS 255 - - #define SCSI_CMD_BUF_SIZE 16 -+#define SCSI_SENSE_LEN 18 -+#define SCSI_INQUIRY_LEN 36 - - typedef struct SCSIBus SCSIBus; - typedef struct SCSIBusInfo SCSIBusInfo; diff --git a/0319-hw-9pfs-Be-robust-against-paths-without-FS_IOC_GETVE.patch b/0319-hw-9pfs-Be-robust-against-paths-without-FS_IOC_GETVE.patch deleted file mode 100644 index cd3bba4..0000000 --- a/0319-hw-9pfs-Be-robust-against-paths-without-FS_IOC_GETVE.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 5ba99e361671bc22bfc3ce45d866826f297e25b7 Mon Sep 17 00:00:00 2001 -From: Gabriel de Perthuis -Date: Fri, 10 May 2013 19:53:28 +0200 -Subject: [PATCH] hw/9pfs: Be robust against paths without FS_IOC_GETVERSION - -9P optionally uses the FS_IOC_GETVERSION ioctl to get information about -a file's version (sometimes called generation number). - -The code checks for supported filesystems at mount time, but some paths -may come from other mounted filesystems. - -Change it to treat unsupported paths the same as unsupported -filesystems, returning 0 in both cases. - -Note: ENOTTY is the error code for an unsupported ioctl. - -This fix allows booting a linux kernel with the same / filesystem as the -host; otherwise the boot fails when mounting devtmpfs. - -Signed-off-by: Gabriel de Perthuis -Reviewed-by: Aneesh Kumar K.V -Signed-off-by: Aneesh Kumar K.V -(cherry picked from commit db431f6adc881a0758512cd765b3108209013512) ---- - hw/9pfs/cofile.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c -index 2efebf3..194c130 100644 ---- a/hw/9pfs/cofile.c -+++ b/hw/9pfs/cofile.c -@@ -38,6 +38,10 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, - }); - v9fs_path_unlock(s); - } -+ /* The ioctl may not be supported depending on the path */ -+ if (err == -ENOTTY) { -+ err = 0; -+ } - return err; - } - diff --git a/0320-hw-9pfs-Fix-errno-value-for-xattr-functions.patch b/0320-hw-9pfs-Fix-errno-value-for-xattr-functions.patch deleted file mode 100644 index 28bed77..0000000 --- a/0320-hw-9pfs-Fix-errno-value-for-xattr-functions.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 79d5a6121844c36239cd4945a4b56e93f10367e8 Mon Sep 17 00:00:00 2001 -From: "Daniel P. Berrange" -Date: Tue, 1 Oct 2013 12:28:17 +0100 -Subject: [PATCH] hw/9pfs: Fix errno value for xattr functions - -If there is no operation driver for the xattr type the -functions return '-1' and set errno to '-EOPNOTSUPP'. -When the calling code sets 'ret = -errno' this turns -into a large positive number. - -In Linux 3.11, the kernel has switched to using 9p -version 9p2000.L, instead of 9p2000.u, which enables -support for xattr operations. This on its own is harmless, -but for another change which makes it request the xattr -with a name 'security.capability'. - -The result is that the guest sees a succesful return -of 95 bytes of data, instead of a failure with errno -set to 95. Since the kernel expects a maximum of 20 -bytes for an xattr return this gets translated to the -unexpected errno ERANGE. - -This all means that when running a binary off a 9p fs -in 3.11 kernels you get a fun result of: - - # ./date - sh: ./date: Numerical result out of range - -The only workaround is to pass 'version=9p2000.u' when -mounting the 9p fs in the guest, to disable all use of -xattrs. - -Signed-off-by: Daniel P. Berrange ---- - hw/9pfs/virtio-9p-xattr.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c -index a839606..2115eee 100644 ---- a/hw/9pfs/virtio-9p-xattr.c -+++ b/hw/9pfs/virtio-9p-xattr.c -@@ -36,7 +36,7 @@ ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, - if (xops) { - return xops->getxattr(ctx, path, name, value, size); - } -- errno = -EOPNOTSUPP; -+ errno = EOPNOTSUPP; - return -1; - } - -@@ -123,7 +123,7 @@ int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, - if (xops) { - return xops->setxattr(ctx, path, name, value, size, flags); - } -- errno = -EOPNOTSUPP; -+ errno = EOPNOTSUPP; - return -1; - - } -@@ -135,7 +135,7 @@ int v9fs_remove_xattr(FsContext *ctx, - if (xops) { - return xops->removexattr(ctx, path, name); - } -- errno = -EOPNOTSUPP; -+ errno = EOPNOTSUPP; - return -1; - - } diff --git a/0321-seccomp-fine-tuning-whitelist-by-adding-times.patch b/0321-seccomp-fine-tuning-whitelist-by-adding-times.patch deleted file mode 100644 index 1549d87..0000000 --- a/0321-seccomp-fine-tuning-whitelist-by-adding-times.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 705cdb391bcd6e116cf632c175a881493d481e94 Mon Sep 17 00:00:00 2001 -From: Eduardo Otubo -Date: Tue, 24 Sep 2013 14:50:44 -0300 -Subject: [PATCH] seccomp: fine tuning whitelist by adding times() - -This was causing Qemu process to hang when using -sandbox on as -discribed on RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1004175 - -Signed-off-by: Eduardo Otubo -Tested-by: Paul Moore -Acked-by: Paul Moore -(cherry picked from commit c236f4519c9838801798f3705c17dce9ab9e3b9d) ---- - qemu-seccomp.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/qemu-seccomp.c b/qemu-seccomp.c -index 031da1d..4a57b4b 100644 ---- a/qemu-seccomp.c -+++ b/qemu-seccomp.c -@@ -96,6 +96,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { - { SCMP_SYS(getuid), 245 }, - { SCMP_SYS(geteuid), 245 }, - { SCMP_SYS(timer_create), 245 }, -+ { SCMP_SYS(times), 245 }, - { SCMP_SYS(exit), 245 }, - { SCMP_SYS(clock_gettime), 245 }, - { SCMP_SYS(time), 245 }, diff --git a/qemu.spec b/qemu.spec index 1e5e5bf..95b1def 100644 --- a/qemu.spec +++ b/qemu.spec @@ -29,6 +29,7 @@ %bcond_without seccomp # enabled %bcond_with xfsprogs # disabled %bcond_with separate_kvm # disabled - for EPEL +%bcond_with gtk # disabled %else # General defaults: %bcond_with kvmonly # disabled @@ -38,14 +39,15 @@ %bcond_without seccomp # enabled %bcond_without xfsprogs # enabled %bcond_with separate_kvm # disabled +%bcond_without gtk # enabled %endif -%global SLOF_gittagdate 20121018 +%global SLOF_gittagdate 20130430 %if %{without separate_kvm} -%global kvm_archs %{ix86} x86_64 ppc64 s390x +%global kvm_archs %{ix86} x86_64 ppc64 s390x armv7hl %else -%global kvm_archs %{ix86} ppc64 s390x +%global kvm_archs %{ix86} ppc64 s390x armv7hl %endif %if %{with exclusive_x86_64} %global kvm_archs x86_64 @@ -98,6 +100,11 @@ %global kvm_target s390x %global need_kvm_modfile 1 %endif +%ifarch armv7hl +%global system_arm kvm +%global kvm_package system-arm +%global kvm_target arm +%endif %if %{with kvmonly} # If kvmonly, put the qemu-kvm binary in the qemu-kvm package @@ -121,6 +128,7 @@ %global system_x86 system-x86 %global system_xtensa system-xtensa %global system_unicore32 system-unicore32 +%global system_moxie system-moxie %endif # libfdt is only needed to build ARM, Microblaze or PPC emulators @@ -130,9 +138,8 @@ Summary: QEMU is a FAST! processor emulator Name: qemu -Version: 1.4.2 -Release: 15%{?dist} -# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped +Version: 1.7.0 +Release: 5%{?dist} Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD Group: Development/Tools @@ -149,7 +156,6 @@ ExclusiveArch: %{kvm_archs} Source0: http://wiki.qemu-project.org/download/%{name}-%{version}.tar.bz2 - Source1: qemu.binfmt # Loads kvm kernel modules at boot @@ -173,150 +179,42 @@ Source12: bridge.conf # qemu-kvm back compat wrapper Source13: qemu-kvm.sh -# Flow control series -Patch0001: 0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch -Patch0002: 0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch -Patch0003: 0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch -Patch0004: 0004-char-Add-framework-for-a-write-unblocked-callback.patch -Patch0005: 0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch -Patch0006: 0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch -Patch0007: 0007-virtio-console-Enable-port-throttling-when-chardev-i.patch -Patch0008: 0008-spice-qemu-char.c-add-throttling.patch -Patch0009: 0009-spice-qemu-char.c-remove-intermediate-buffer.patch -Patch0010: 0010-usb-redir-Add-flow-control-support.patch -Patch0011: 0011-char-Disable-write-callback-if-throttled-chardev-is-.patch -Patch0012: 0012-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch - -# Fix migration crash with spice (bz #962954) -Patch0101: 0101-vnc-tls-Fix-compilation-with-newer-versions-of-GNU-T.patch -Patch0102: 0102-migration-change-initial-value-of-expected_downtime.patch -Patch0103: 0103-migration-calculate-end-time-after-we-have-sent-the-.patch -Patch0104: 0104-migration-don-t-account-sleep-time-for-calculating-b.patch -Patch0105: 0105-migration-calculate-expected_downtime.patch -Patch0106: 0106-migration-simplify-while-loop.patch -Patch0107: 0107-migration-always-use-vm_stop_force_state.patch -Patch0108: 0108-migration-move-more-error-handling-to-migrate_fd_cle.patch -Patch0109: 0109-migration-push-qemu_savevm_state_cancel-out-of-qemu_.patch -Patch0110: 0110-block-migration-remove-useless-calls-to-blk_mig_clea.patch -Patch0111: 0111-qemu-file-pass-errno-from-qemu_fflush-via-f-last_err.patch -Patch0112: 0112-migration-use-qemu_file_set_error-to-pass-error-code.patch -Patch0113: 0113-qemu-file-temporarily-expose-qemu_file_set_error-and.patch -Patch0114: 0114-migration-flush-all-data-to-fd-when-buffered_flush-i.patch -Patch0115: 0115-migration-use-qemu_file_set_error.patch -Patch0116: 0116-migration-simplify-error-handling.patch -Patch0117: 0117-migration-do-not-nest-flushing-of-device-data.patch -Patch0118: 0118-migration-add-migrate_set_state-tracepoint.patch -Patch0119: 0119-migration-prepare-to-access-s-state-outside-critical.patch -Patch0120: 0120-migration-cleanup-migration-including-thread-in-the-.patch -Patch0121: 0121-block-migration-remove-variables-that-are-never-read.patch -Patch0122: 0122-block-migration-small-preparatory-changes-for-lockin.patch -Patch0123: 0123-block-migration-document-usage-of-state-across-threa.patch -Patch0124: 0124-block-migration-add-lock.patch -Patch0125: 0125-migration-reorder-SaveVMHandlers-members.patch -Patch0126: 0126-migration-run-pending-iterate-callbacks-out-of-big-l.patch -Patch0127: 0127-migration-run-setup-callbacks-out-of-big-lock.patch -Patch0128: 0128-migration-yay-buffering-is-gone.patch -Patch0129: 0129-Rename-buffered_-to-migration_.patch -Patch0130: 0130-qemu-file-make-qemu_fflush-and-qemu_file_set_error-p.patch -Patch0131: 0131-migration-eliminate-last_round.patch -Patch0132: 0132-migration-detect-error-before-sleeping.patch -Patch0133: 0133-migration-remove-useless-qemu_file_get_error-check.patch -Patch0134: 0134-migration-use-qemu_file_rate_limit-consistently.patch -Patch0135: 0135-migration-merge-qemu_popen_cmd-with-qemu_popen.patch -Patch0136: 0136-qemu-file-fsync-a-writable-stdio-QEMUFile.patch -Patch0137: 0137-qemu-file-check-exit-status-when-closing-a-pipe-QEMU.patch -Patch0138: 0138-qemu-file-add-writable-socket-QEMUFile.patch -Patch0139: 0139-qemu-file-simplify-and-export-qemu_ftell.patch -Patch0140: 0140-migration-use-QEMUFile-for-migration-channel-lifetim.patch -Patch0141: 0141-migration-use-QEMUFile-for-writing-outgoing-migratio.patch -Patch0142: 0142-migration-use-qemu_ftell-to-compute-bandwidth.patch -Patch0143: 0143-migration-small-changes-around-rate-limiting.patch -Patch0144: 0144-migration-move-rate-limiting-to-QEMUFile.patch -Patch0145: 0145-migration-move-contents-of-migration_close-to-migrat.patch -Patch0146: 0146-migration-eliminate-s-migration_file.patch -Patch0147: 0147-migration-inline-migrate_fd_close.patch -Patch0148: 0148-Revert-migration-don-t-account-sleep-time-for-calcul.patch - -# 917860 libcacard and qemu/hw/ccid windows 7 smartcard support. -Patch0201: 0201-configure-Add-enable-migration-from-qemu-kvm.patch -Patch0202: 0202-acpi_piix4-Drop-minimum_version_id-to-handle-qemu-kv.patch -Patch0203: 0203-i8254-Fix-migration-from-qemu-kvm-1.1.patch -Patch0204: 0204-pc_piix-Add-compat-handling-for-qemu-kvm-VGA-mem-siz.patch -Patch0205: 0205-qxl-Add-rom_size-compat-property-fix-migration-from-.patch -Patch0206: 0206-rtl8139-flush-queued-packets-when-RxBufPtr-is-writte.patch -Patch0207: 0207-spice-qemu-char-vmc_write-Don-t-write-more-bytes-the.patch -Patch0208: 0208-configure-dtc-Probe-for-libfdt_env.h.patch -Patch0209: 0209-Fix-usage-of-USB_DEV_FLAG_IS_HOST-flag.patch -Patch0210: 0210-qxl-Fix-QXLRam-initialisation.patch -Patch0211: 0211-qemu-socket-Make-socket_optslist-public.patch -Patch0212: 0212-libcacard-correct-T0-historical-bytes-size.patch -Patch0213: 0213-ccid-card-emul-do-not-crash-if-backend-is-not-provid.patch -Patch0214: 0214-ccid-make-backend_enum_table-static-const-and-adjust.patch -Patch0215: 0215-ccid-declare-DEFAULT_ATR-table-to-be-static-const.patch -Patch0216: 0216-libcacard-use-system-config-directory-for-nss-db-on-.patch -Patch0217: 0217-util-move-socket_init-to-osdep.c.patch -Patch0218: 0218-build-sys-must-link-with-fstack-protector.patch -Patch0219: 0219-libcacard-fix-mingw64-cross-compilation.patch -Patch0220: 0220-libcacard-split-vscclient-main-from-socket-reading.patch -Patch0221: 0221-libcacard-vscclient-to-use-QemuThread-for-portabilit.patch -Patch0222: 0222-libcacard-teach-vscclient-to-use-GMainLoop-for-porta.patch -Patch0223: 0223-libcacard-remove-sql-prefix.patch -Patch0224: 0224-libcacard-remove-default-libcoolkey-loading.patch -Patch0225: 0225-dev-smartcard-reader-white-space-fixes.patch -Patch0226: 0226-dev-smartcard-reader-nicer-debug-messages.patch -Patch0227: 0227-dev-smartcard-reader-remove-aborts-never-triggered-b.patch -Patch0228: 0228-dev-smartcard-reader-support-windows-guest.patch -Patch0229: 0229-dev-smartcard-reader-reuse-usb.h-definitions.patch -Patch0230: 0230-libcacard-change-default-ATR.patch -Patch0231: 0231-ccid-card-passthru-add-atr-check.patch - -# qemu-kvm migration compat (posted upstream) -Patch0301: 0301-ccid-card-passthru-dev-smartcard-reader-add-debug-en.patch -Patch0302: 0302-dev-smartcard-reader-define-structs-for-CCID_Paramet.patch -Patch0303: 0303-dev-smartcard-reader-change-default-protocol-to-T-0.patch -Patch0304: 0304-dev-smartcard-reader-copy-atr-protocol-to-ccid-param.patch -Patch0305: 0305-libcacard-vreader-add-debugging-messages-for-apdu.patch -# Fix rtl8139 + windows 7 + large transfers (bz #970240) -Patch0306: 0306-libcacard-move-atr-setting-from-macro-to-function.patch -# Fix crash on large drag and drop file transfer w/ spice (bz #969109) -Patch0307: 0307-dev-smartcard-reader-empty-implementation-for-Mechan.patch -# Fix build with latest libfdt -Patch0308: 0308-libcacard-cac-change-big-switch-functions-to-single-.patch -# Fix usb_handle_packet assertions (bz #981459) -Patch0309: 0309-libcacard-vscclient-fix-leakage-of-socket-on-error-p.patch -# Fix crash when adding spice vdagent channel in the guest (bz #969084) -Patch0310: 0310-libcacard-Fix-cppcheck-warning-and-remove-unneeded-c.patch -# Fix crash with -M isapc -cpu Haswell (bz #986790) -Patch0311: 0311-isapc-disable-kvmvapic.patch # Fix crash in lsi_soft_reset (bz #1000947) # Patches posted upstream -Patch0312: 0312-pci-do-not-export-pci_bus_reset.patch -Patch0313: 0313-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch -Patch0314: 0314-qdev-switch-reset-to-post-order.patch -# Fix crash in scsi_dma_complete (bz #1001617) -Patch0315: 0315-scsi-avoid-assertion-failure-on-VERIFY-command.patch -# ppc64 hangs at "Trying to read invalid spr 896 380 at .." (bz -# #1004532) -Patch0316: 0316-target-ppc-Add-read-and-write-of-PPR-SPR.patch -# Fix screenshots for qxl kernel driver (bz #948717) -Patch0317: 0317-qxl-fix-local-renderer.patch -# CVE-2013-4344: buffer overflow in scsi_target_emulate_report_luns (bz -# #1015274, bz #1007330) -Patch0318: 0318-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch -# Fix 9pfs xattrs on kernel 3.11 (bz #1013676) -Patch0319: 0319-hw-9pfs-Be-robust-against-paths-without-FS_IOC_GETVE.patch -Patch0320: 0320-hw-9pfs-Fix-errno-value-for-xattr-functions.patch -# Fix process exit with -sandbox on (bz #1027421) -Patch0321: 0321-seccomp-fine-tuning-whitelist-by-adding-times.patch +Patch0001: 0001-pci-do-not-export-pci_bus_reset.patch +Patch0002: 0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch +Patch0003: 0003-qdev-switch-reset-to-post-order.patch +# CVE-2013-4377: Fix crash when unplugging virtio devices (bz #1012633, +# bz #1012641) +# Patches posted upstream +Patch0004: 0004-virtio-bus-remove-vdev-field.patch +Patch0005: 0005-virtio-pci-remove-vdev-field.patch +Patch0006: 0006-virtio-ccw-remove-vdev-field.patch +Patch0007: 0007-virtio-bus-cleanup-plug-unplug-interface.patch +Patch0008: 0008-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch +Patch0009: 0009-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch +Patch0010: 0010-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch +Patch0011: 0011-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch +Patch0012: 0012-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch +Patch0013: 0013-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch +Patch0014: 0014-virtio-pci-add-device_unplugged-callback.patch + +# Fix qemu-img create with NBD backing file (bz #1034433) +# Patch posted upstream +Patch0101: 0101-block-Close-backing-file-early-in-bdrv_img_create.patch # Add kill() to seccomp whitelist, fix AC97 with -sandbox on (bz # #1043521) -Patch0322: 0322-seccomp-add-kill-to-the-syscall-whitelist.patch +Patch0102: 0102-seccomp-add-kill-to-the-syscall-whitelist.patch # Changing streaming mode default to off for spice (bz #1038336) -Patch0323: 0323-spice-flip-streaming-video-mode-to-off-by-default.patch +Patch0103: 0103-spice-flip-streaming-video-mode-to-off-by-default.patch +# Fix guest scsi verify command (bz #1001617) +Patch0104: 0104-scsi-bus-fix-transfer-length-and-direction-for-VERIF.patch +Patch0105: 0105-scsi-disk-fix-VERIFY-emulation.patch BuildRequires: SDL-devel BuildRequires: zlib-devel BuildRequires: which +BuildRequires: chrpath BuildRequires: texi2html BuildRequires: gnutls-devel BuildRequires: cyrus-sasl-devel @@ -341,7 +239,7 @@ BuildRequires: spice-protocol >= 0.12.2 BuildRequires: spice-server-devel >= 0.12.0 %endif %if 0%{?have_seccomp:1} -BuildRequires: libseccomp-devel >= 1.0.0 +BuildRequires: libseccomp-devel >= 2.1.0 %endif # For network block driver BuildRequires: libcurl-devel @@ -372,8 +270,6 @@ BuildRequires: brlapi-devel # For FDT device tree support BuildRequires: libfdt-devel %endif -# For test suite -BuildRequires: check-devel # For virtfs BuildRequires: libcap-devel # Hard requirement for version >= 1.3 @@ -383,6 +279,29 @@ BuildRequires: pixman-devel BuildRequires: glusterfs-devel >= 3.4.0 BuildRequires: glusterfs-api-devel >= 3.4.0 %endif +# Needed for usb passthrough for qemu >= 1.5 +BuildRequires: libusbx-devel +# SSH block driver +%if 0%{?fedora} >= 20 +BuildRequires: libssh2-devel +%endif +%if %{with gtk} +# GTK frontend +BuildRequires: gtk3-devel +BuildRequires: vte3-devel +%endif +# GTK translations +BuildRequires: gettext +# RDMA migration +%ifnarch s390 s390x +BuildRequires: librdmacm-devel +%endif +# For sanity test +%if 0%{?fedora} >= 20 +BuildRequires: qemu-sanity-check-nodeps +BuildRequires: kernel +%endif +BuildRequires: iasl %if 0%{?user:1} Requires: %{name}-%{user} = %{epoch}:%{version}-%{release} @@ -432,6 +351,9 @@ Requires: %{name}-%{system_x86} = %{epoch}:%{version}-%{release} %if 0%{?system_xtensa:1} Requires: %{name}-%{system_xtensa} = %{epoch}:%{version}-%{release} %endif +%if 0%{?system_moxie:1} +Requires: %{name}-%{system_moxie} = %{epoch}:%{version}-%{release} +%endif %if %{without separate_kvm} Requires: %{name}-img = %{epoch}:%{version}-%{release} %else @@ -471,13 +393,6 @@ will install qemu-system-x86 Summary: QEMU command line tool for manipulating disk images Group: Development/Tools -# ceph added new symbol rbd_aio_flush which qemu wants to use, but ceph -# lacks symbol versioning so RPM doesn't pick up the dependency. -# Need to keep this for the lifetime of f19 -%if %{with rbd} -Requires: ceph-libs >= 0.61 -%endif - %description img This package provides a command line tool for manipulating disk images @@ -491,13 +406,6 @@ Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units -# ceph added new symbol rbd_aio_flush which qemu wants to use, but ceph -# lacks symbol versioning so RPM doesn't pick up the dependency. -# Need to keep this for the lifetime of f19 -%if %{with rbd} -Requires: ceph-libs >= 0.61 -%endif - %description common QEMU is a generic and open source processor emulator which achieves a good emulation speed by using dynamic translation. @@ -565,9 +473,10 @@ Requires: %{name}-common = %{epoch}:%{version}-%{release} Provides: kvm = 85 Obsoletes: kvm < 85 Requires: seavgabios-bin -Requires: seabios-bin >= 0.6.0-2 +# First version that ships aml files which we depend on +Requires: seabios-bin >= 1.7.3-2 Requires: sgabios-bin -Requires: ipxe-roms-qemu +Requires: ipxe-roms-qemu >= 20130517-2.gitc4bce43 %if 0%{?have_seccomp:1} Requires: libseccomp >= 1.0.0 %endif @@ -720,7 +629,7 @@ Summary: QEMU system emulator for PPC Group: Development/Tools Requires: %{name}-common = %{epoch}:%{version}-%{release} Requires: openbios -Requires: SLOF = 0.1.git%{SLOF_gittagdate} +Requires: SLOF >= 0.1.git%{SLOF_gittagdate} %description %{system_ppc} QEMU is a generic and open source processor emulator which achieves a good emulation speed by using dynamic translation. @@ -752,6 +661,18 @@ emulation speed by using dynamic translation. This package provides the system emulator for Unicore32 boards. %endif +%if 0%{?system_moxie:1} +%package %{system_moxie} +Summary: QEMU system emulator for Moxie +Group: Development/Tools +Requires: %{name}-common = %{epoch}:%{version}-%{release} +%description %{system_moxie} +QEMU is a generic and open source processor emulator which achieves a good +emulation speed by using dynamic translation. + +This package provides the system emulator for Moxie boards. +%endif + %ifarch %{kvm_archs} %package kvm-tools Summary: KVM debugging and diagnostics tools @@ -788,12 +709,16 @@ CAC emulation development files. %endif %prep -%setup -q +%setup -q -n qemu-1.7.0 -# Flow control series +# Fix crash in lsi_soft_reset (bz #1000947) +# Patches posted upstream %patch0001 -p1 %patch0002 -p1 %patch0003 -p1 +# CVE-2013-4377: Fix crash when unplugging virtio devices (bz #1012633, +# bz #1012641) +# Patches posted upstream %patch0004 -p1 %patch0005 -p1 %patch0006 -p1 @@ -803,133 +728,21 @@ CAC emulation development files. %patch0010 -p1 %patch0011 -p1 %patch0012 -p1 +%patch0013 -p1 +%patch0014 -p1 -# Fix migration crash with spice (bz #962954) +# Fix qemu-img create with NBD backing file (bz #1034433) +# Patch posted upstream %patch0101 -p1 -%patch0102 -p1 -%patch0103 -p1 -%patch0104 -p1 -%patch0105 -p1 -%patch0106 -p1 -%patch0107 -p1 -%patch0108 -p1 -%patch0109 -p1 -%patch0110 -p1 -%patch0111 -p1 -%patch0112 -p1 -%patch0113 -p1 -%patch0114 -p1 -%patch0115 -p1 -%patch0116 -p1 -%patch0117 -p1 -%patch0118 -p1 -%patch0119 -p1 -%patch0120 -p1 -%patch0121 -p1 -%patch0122 -p1 -%patch0123 -p1 -%patch0124 -p1 -%patch0125 -p1 -%patch0126 -p1 -%patch0127 -p1 -%patch0128 -p1 -%patch0129 -p1 -%patch0130 -p1 -%patch0131 -p1 -%patch0132 -p1 -%patch0133 -p1 -%patch0134 -p1 -%patch0135 -p1 -%patch0136 -p1 -%patch0137 -p1 -%patch0138 -p1 -%patch0139 -p1 -%patch0140 -p1 -%patch0141 -p1 -%patch0142 -p1 -%patch0143 -p1 -%patch0144 -p1 -%patch0145 -p1 -%patch0146 -p1 -%patch0147 -p1 -%patch0148 -p1 - -# 917860 libcacard and qemu/hw/ccid windows 7 smartcard support. -%patch0201 -p1 -%patch0202 -p1 -%patch0203 -p1 -%patch0204 -p1 -%patch0205 -p1 -%patch0206 -p1 -%patch0207 -p1 -%patch0208 -p1 -%patch0209 -p1 -%patch0210 -p1 -%patch0211 -p1 -%patch0212 -p1 -%patch0213 -p1 -%patch0214 -p1 -%patch0215 -p1 -%patch0216 -p1 -%patch0217 -p1 -%patch0218 -p1 -%patch0219 -p1 -%patch0220 -p1 -%patch0221 -p1 -%patch0222 -p1 -%patch0223 -p1 -%patch0224 -p1 -%patch0225 -p1 -%patch0226 -p1 -%patch0227 -p1 -%patch0228 -p1 -%patch0229 -p1 -%patch0230 -p1 -%patch0231 -p1 - -# qemu-kvm migration compat (posted upstream) -%patch0301 -p1 -%patch0302 -p1 -%patch0303 -p1 -%patch0304 -p1 -%patch0305 -p1 -# Fix rtl8139 + windows 7 + large transfers (bz #970240) -%patch0306 -p1 -# Fix crash on large drag and drop file transfer w/ spice (bz #969109) -%patch0307 -p1 -# Fix build with latest libfdt -%patch0308 -p1 -# Fix usb_handle_packet assertions (bz #981459) -%patch0309 -p1 -# Fix crash when adding spice vdagent channel in the guest (bz #969084) -%patch0310 -p1 -# Fix crash with -M isapc -cpu Haswell (bz #986790) -%patch0311 -p1 -# Fix crash in lsi_soft_reset (bz #1000947) -# Patches posted upstream -%patch0312 -p1 -%patch0313 -p1 -%patch0314 -p1 -# Fix crash in scsi_dma_complete (bz #1001617) -%patch0315 -p1 -# ppc64 hangs at "Trying to read invalid spr 896 380 at .." (bz -# #1004532) -%patch0316 -p1 -# Fix screenshots for qxl kernel driver (bz #948717) -%patch0317 -p1 -# CVE-2013-4344: buffer overflow in scsi_target_emulate_report_luns (bz -# #1015274, bz #1007330) -%patch0318 -p1 -# Fix 9pfs xattrs on kernel 3.11 (bz #1013676) -%patch0319 -p1 -%patch0320 -p1 -# Fix process exit with -sandbox on (bz #1027421) -%patch0321 -p1 # Add kill() to seccomp whitelist, fix AC97 with -sandbox on (bz # #1043521) -%patch0322 -p1 +%patch0102 -p1 # Changing streaming mode default to off for spice (bz #1038336) -%patch0323 -p1 +%patch0103 -p1 +# Fix guest scsi verify command (bz #1001617) +%patch0104 -p1 +%patch0105 -p1 + %build %if %{with kvmonly} @@ -940,11 +753,13 @@ CAC emulation development files. microblazeel-softmmu mips-softmmu mipsel-softmmu mips64-softmmu \ mips64el-softmmu or32-softmmu ppc-softmmu ppcemb-softmmu ppc64-softmmu \ s390x-softmmu sh4-softmmu sh4eb-softmmu sparc-softmmu sparc64-softmmu \ - xtensa-softmmu xtensaeb-softmmu unicore32-softmmu \ + xtensa-softmmu xtensaeb-softmmu unicore32-softmmu moxie-softmmu \ i386-linux-user x86_64-linux-user alpha-linux-user arm-linux-user \ armeb-linux-user cris-linux-user m68k-linux-user \ microblaze-linux-user microblazeel-linux-user mips-linux-user \ - mipsel-linux-user or32-linux-user ppc-linux-user ppc64-linux-user \ + mipsel-linux-user mips64-linux-user mips64el-linux-user \ + mipsn32-linux-user mipsn32el-linux-user \ + or32-linux-user ppc-linux-user ppc64-linux-user \ ppc64abi32-linux-user s390x-linux-user sh4-linux-user sh4eb-linux-user \ sparc-linux-user sparc64-linux-user sparc32plus-linux-user \ unicore32-linux-user" @@ -967,23 +782,26 @@ dobuild() { --libdir=%{_libdir} \ --sysconfdir=%{_sysconfdir} \ --interp-prefix=%{_prefix}/qemu-%%M \ - --audio-drv-list=pa,sdl,alsa,oss \ --localstatedir=%{_localstatedir} \ --libexecdir=%{_libexecdir} \ --disable-strip \ --extra-ldflags="$extraldflags -pie -Wl,-z,relro -Wl,-z,now" \ --extra-cflags="%{optflags} -fPIE -DPIE" \ - --enable-mixemu \ - --enable-trace-backend=dtrace \ --disable-werror \ + --audio-drv-list=pa,sdl,alsa,oss \ + --enable-trace-backend=dtrace \ --disable-xen \ --enable-kvm \ - --enable-migration-from-qemu-kvm \ + --enable-tpm \ %if 0%{?have_spice:1} --enable-spice \ +%else + --disable-spice \ %endif %if 0%{?have_seccomp:1} --enable-seccomp \ +%else + --disable-seccomp \ %endif %if %{without rbd} --disable-rbd \ @@ -992,6 +810,12 @@ dobuild() { --enable-fdt \ %else --disable-fdt \ +%endif +%if %{with gtk} + --with-gtkabi="3.0" \ +%endif +%ifarch s390 + --enable-tcg-interpreter \ %endif "$@" @@ -1007,6 +831,12 @@ dobuild --target-list="$buildarch" gcc %{SOURCE6} -O2 -g -o ksmctl +# Check the binary runs (see eg RHBZ#998722). +%ifarch %{kvm_archs} +b="./x86_64-softmmu/qemu-system-x86_64" +if [ -x "$b" ]; then "$b" -help; fi +%endif + %install @@ -1035,6 +865,8 @@ install -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_udevdir} make DESTDIR=$RPM_BUILD_ROOT install +%find_lang %{name} + %if 0%{?need_qemu_kvm} install -m 0755 %{SOURCE13} $RPM_BUILD_ROOT%{_bindir}/qemu-kvm %endif @@ -1045,7 +877,7 @@ rm $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/qemu-system-%{kvm_target}.stp %endif chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/* -install -D -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README TODO COPYING COPYING.LIB LICENSE +install -D -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README COPYING COPYING.LIB LICENSE for emu in $RPM_BUILD_ROOT%{_bindir}/qemu-system-*; do ln -sf qemu.1.gz $RPM_BUILD_ROOT%{_mandir}/man1/$(basename $emu).1.gz done @@ -1080,14 +912,21 @@ rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{name}/spapr-rtas.bin %endif %if 0%{!?system_s390x:1} rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/s390-zipl.rom +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/s390-ccw.img +%endif +%if 0%{!?system_sparc:1} +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/QEMU,tcx.bin %endif # Provided by package ipxe rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/pxe*rom +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/efi*rom # Provided by package seavgabios rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/vgabios*bin # Provided by package seabios rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/bios.bin +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/acpi-dsdt.aml +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/q35-acpi-dsdt.aml # Provided by package sgabios rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/sgabios.bin @@ -1097,6 +936,7 @@ rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/sgabios.bin # for other paths, yet. pxe_link() { ln -s ../ipxe/$2.rom %{buildroot}%{_datadir}/%{name}/pxe-$1.rom + ln -s ../ipxe.efi/$2.rom %{buildroot}%{_datadir}/%{name}/efi-$1.rom } pxe_link e1000 8086100e @@ -1115,6 +955,8 @@ rom_link ../seavgabios/vgabios-qxl.bin vgabios-qxl.bin rom_link ../seavgabios/vgabios-stdvga.bin vgabios-stdvga.bin rom_link ../seavgabios/vgabios-vmware.bin vgabios-vmware.bin rom_link ../seabios/bios.bin bios.bin +rom_link ../seabios/acpi-dsdt.aml acpi-dsdt.aml +rom_link ../seabios/q35-acpi-dsdt.aml q35-acpi-dsdt.aml rom_link ../sgabios/sgabios.bin sgabios.bin %endif @@ -1200,8 +1042,40 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/libcacard.pc rm -rf $RPM_BUILD_ROOT%{_includedir}/cacard %endif +# When building using 'rpmbuild' or 'fedpkg local', RPATHs can be left in +# the binaries and libraries (although this doesn't occur when +# building in Koji, for some unknown reason). Some discussion here: +# +# https://lists.fedoraproject.org/pipermail/devel/2013-November/192553.html +# +# In any case it should always be safe to remove RPATHs from +# the final binaries: +for f in $RPM_BUILD_ROOT%{_bindir}/* $RPM_BUILD_ROOT%{_libdir}/* \ + $RPM_BUILD_ROOT%{_libexecdir}/*; do + if file $f | grep -q ELF; then chrpath --delete $f; fi +done + %check +# Disabled on aarch64 where it fails with several errors. Will +# investigate and fix when we have access to real hardware - RWMJ. +%ifnarch aarch64 make check +%endif + +# Sanity-check current kernel can boot on this qemu. +# The results are advisory only. +%if 0%{?fedora} >= 20 +%ifarch %{arm} +hostqemu=arm-softmmu/qemu-system-arm +%endif +%ifarch %{ix86} +hostqemu=i386-softmmu/qemu-system-i386 +%endif +%ifarch x86_64 +hostqemu=x86_64-softmmu/qemu-system-x86_64 +%endif +if test -f "$hostqemu"; then qemu-sanity-check --qemu=$hostqemu ||: ; fi +%endif %ifarch %{kvm_archs} %post %{kvm_package} @@ -1231,6 +1105,10 @@ getent passwd qemu >/dev/null || \ %systemd_postun_with_restart ksmtuned.service %endif +%if %{without separate_kvm} +%post -n libcacard -p /sbin/ldconfig +%postun -n libcacard -p /sbin/ldconfig +%endif %if 0%{?user:1} %post %{user} @@ -1260,12 +1138,11 @@ getent passwd qemu >/dev/null || \ %defattr(-,root,root) %endif -%files common +%files common -f %{name}.lang %defattr(-,root,root) %dir %{qemudocdir} %doc %{qemudocdir}/Changelog %doc %{qemudocdir}/README -%doc %{qemudocdir}/TODO %doc %{qemudocdir}/qemu-doc.html %doc %{qemudocdir}/qemu-tech.html %doc %{qemudocdir}/qmp-commands.txt @@ -1273,6 +1150,8 @@ getent passwd qemu >/dev/null || \ %doc %{qemudocdir}/COPYING.LIB %doc %{qemudocdir}/LICENSE %dir %{_datadir}/%{name}/ +%{_datadir}/%{name}/qemu-icon.bmp +%{_datadir}/%{name}/qemu_logo_no_text.svg %{_datadir}/%{name}/keymaps/ %{_mandir}/man1/qemu.1* %{_mandir}/man1/virtfs-proxy-helper.1* @@ -1316,6 +1195,10 @@ getent passwd qemu >/dev/null || \ %{_bindir}/qemu-microblazeel %{_bindir}/qemu-mips %{_bindir}/qemu-mipsel +%{_bindir}/qemu-mips64 +%{_bindir}/qemu-mips64el +%{_bindir}/qemu-mipsn32 +%{_bindir}/qemu-mipsn32el %{_bindir}/qemu-or32 %{_bindir}/qemu-ppc %{_bindir}/qemu-ppc64 @@ -1338,6 +1221,10 @@ getent passwd qemu >/dev/null || \ %{_datadir}/systemtap/tapset/qemu-microblazeel.stp %{_datadir}/systemtap/tapset/qemu-mips.stp %{_datadir}/systemtap/tapset/qemu-mipsel.stp +%{_datadir}/systemtap/tapset/qemu-mips64.stp +%{_datadir}/systemtap/tapset/qemu-mips64el.stp +%{_datadir}/systemtap/tapset/qemu-mipsn32.stp +%{_datadir}/systemtap/tapset/qemu-mipsn32el.stp %{_datadir}/systemtap/tapset/qemu-or32.stp %{_datadir}/systemtap/tapset/qemu-ppc.stp %{_datadir}/systemtap/tapset/qemu-ppc64.stp @@ -1375,11 +1262,15 @@ getent passwd qemu >/dev/null || \ %{_datadir}/%{name}/vgabios-stdvga.bin %{_datadir}/%{name}/vgabios-vmware.bin %{_datadir}/%{name}/pxe-e1000.rom +%{_datadir}/%{name}/efi-e1000.rom %{_datadir}/%{name}/pxe-virtio.rom +%{_datadir}/%{name}/efi-virtio.rom %{_datadir}/%{name}/pxe-pcnet.rom +%{_datadir}/%{name}/efi-pcnet.rom %{_datadir}/%{name}/pxe-rtl8139.rom +%{_datadir}/%{name}/efi-rtl8139.rom %{_datadir}/%{name}/pxe-ne2k_pci.rom -%{_datadir}/%{name}/qemu-icon.bmp +%{_datadir}/%{name}/efi-ne2k_pci.rom %config(noreplace) %{_sysconfdir}/qemu/target-x86_64.conf %if %{without separate_kvm} %ifarch %{ix86} x86_64 @@ -1410,6 +1301,13 @@ getent passwd qemu >/dev/null || \ %{_bindir}/qemu-system-arm %{_datadir}/systemtap/tapset/qemu-system-arm.stp %{_mandir}/man1/qemu-system-arm.1* +%if %{without separate_kvm} +%ifarch armv7hl +%{?kvm_files:} +%{?qemu_kvm_files:} +%endif +%endif + %endif %if 0%{?system_mips:1} @@ -1480,6 +1378,7 @@ getent passwd qemu >/dev/null || \ %{_datadir}/systemtap/tapset/qemu-system-s390x.stp %{_mandir}/man1/qemu-system-s390x.1* %{_datadir}/%{name}/s390-zipl.rom +%{_datadir}/%{name}/s390-ccw.img %ifarch s390x %{?kvm_files:} %{?qemu_kvm_files:} @@ -1506,6 +1405,7 @@ getent passwd qemu >/dev/null || \ %{_datadir}/systemtap/tapset/qemu-system-sparc64.stp %{_mandir}/man1/qemu-system-sparc.1* %{_mandir}/man1/qemu-system-sparc64.1* +%{_datadir}/%{name}/QEMU,tcx.bin %endif %if 0%{?system_ppc:1} @@ -1550,6 +1450,14 @@ getent passwd qemu >/dev/null || \ %{_mandir}/man1/qemu-system-xtensaeb.1* %endif +%if 0%{?system_moxie:1} +%files %{system_moxie} +%defattr(-,root,root) +%{_bindir}/qemu-system-moxie +%{_datadir}/systemtap/tapset/qemu-system-moxie.stp +%{_mandir}/man1/qemu-system-moxie.1* +%endif + %if %{without separate_kvm} %files img %defattr(-,root,root) @@ -1576,68 +1484,153 @@ getent passwd qemu >/dev/null || \ %endif %changelog -* Wed Dec 18 2013 Cole Robinson - 2:1.4.2-15 +* Tue Feb 18 2014 Richard W.M. Jones - 2:1.7.0-5 +- Run qemu-sanity-check on x86 and armv7 too. The results are still + only advisory. + +* Mon Jan 13 2014 Richard W.M. Jones - 2:1.7.0-4 +- Disable make check on aarch64. + +* Sat Dec 21 2013 Ville Skyttä - 2:1.7.0-3 +- Add libcacard ldconfig %%post* scriptlets. + +* Wed Dec 18 2013 Cole Robinson - 2:1.7.0-2 - Add kill() to seccomp whitelist, fix AC97 with -sandbox on (bz #1043521) - Changing streaming mode default to off for spice (bz #1038336) -- Fix qemu-img ceph dep (bz #1024781) +- Fix guest scsi verify command (bz #1001617) -* Sun Nov 17 2013 Cole Robinson - 2:1.4.2-14 +* Mon Dec 02 2013 Cole Robinson - 2:1.7.0-1 +- Fix qemu-img create with NBD backing file (bz #1034433) +- Rebase to qemu-1.7 GA +- New monitor command blockdev-add for full featured block device hotplug. +- Performance and functionality improvements for USB 3.0. +- Many VFIO improvements +- ACPI tables can be generated by QEMU and can be used by firmware directly. +- Support creating and writing .vhdx images. +- qemu-img map: dump detailed image file metadata + +* Fri Nov 29 2013 Richard W.M. Jones - 2:1.7.0-0.2.rc1 +- Run chrpath on binaries, so qemu can be built using rpmbuild. + +* Thu Nov 21 2013 Cole Robinson - 2:1.7.0-0.1.rc1 +- Update qemu-1.7.0-rc1 + +* Sun Nov 17 2013 Cole Robinson - 2:1.6.1-2 +- Fix drive discard options via libvirt (bz #1029953) - Fix process exit with -sandbox on (bz #1027421) -* Tue Nov 05 2013 Cole Robinson - 2:1.4.2-13 +* Tue Nov 05 2013 Cole Robinson - 2:1.6.1-1 +- Reduce CPU usage when audio is playing (bz #1017644) +- Base on qemu 1.6.1 tarball - ksmtuned: Fix matching qemu w/o set_process_name (bz #1012604) - ksmtuned: Fix committed_memory when no qemu running (bz #1012610) - Make sure bridge helper is setuid (bz #1017660) -* Sun Oct 06 2013 Cole Robinson - 2:1.4.2-12 +* Wed Oct 09 2013 Cole Robinson - 2:1.6.0-10 +- Fix migration from qemu <= 1.5 + +* Sun Oct 06 2013 Cole Robinson - 2:1.6.0-9 +- Rebase to pending 1.6.1 stable +- CVE-2013-4377: Fix crash when unplugging virtio devices (bz #1012633, bz + #1012641) +- Fix 'new snapshot' slowness after the first snap (bz #988436) +- Fix 9pfs xattrs on kernel 3.11 (bz #1013676) - CVE-2013-4344: buffer overflow in scsi_target_emulate_report_luns (bz #1015274, bz #1007330) -- Fix 9pfs xattrs on kernel 3.11 (bz #1013676) -* Wed Sep 25 2013 Alon Levy 2:1.4.2-11 -- Fix screenshots for qxl kernel driver (bz #948717) +* Tue Sep 24 2013 Cole Robinson - 2:1.6.0-8 +- Fix -vga qxl with -display vnc (bz #948717) +- Fix USB crash when installing reactos (bz #1005495) +- Don't ship x86 kvm wrapper on arm (bz #1005581) -* Tue Sep 24 2013 Cole Robinson - 2:1.4.2-10 -- Require newer ceph-libs to fix symbol error (bz #995883) +* Thu Sep 12 2013 Dan Horák - 2:1.6.0-7 +- Enable TCG interpreter for s390 as the native backend supports 64-bit only +- Don't require RDMA on s390(x) -* Thu Sep 05 2013 Richard W.M. Jones - 2:1.4.2-9 -- ppc64 hangs at "Trying to read invalid spr 896 380 at .." (bz #1004532) - -* Tue Sep 03 2013 Cole Robinson - 2:1.4.2-8 +* Tue Sep 03 2013 Cole Robinson - 2:1.6.0-6 +- Fix qmp capabilities calls on i686 (bz #1003162) - Fix crash with -M isapc -cpu Haswell (bz #986790) - Fix crash in lsi_soft_reset (bz #1000947) -- Fix crash in scsi_dma_complete (bz #1001617) - Fix initial /dev/kvm permissions (bz #993491) -* Sun Aug 18 2013 Alon Levy - 2:1.4.2-7 -- Support windows 7 smartcard using guests and clients - (bz #917860 rhel 6.5) +* Wed Aug 28 2013 Richard W.M. Jones - 2:1.6.0-5 +- Enable qemu-sanity-check, however do not fail the build if it fails. -* Thu Aug 01 2013 Cole Robinson - 2:1.4.2-6 -- Fix crash when adding spice vdagent channel in the guest (bz #969084) +* Wed Aug 21 2013 Richard W.M. Jones - 2:1.6.0-4 +- Require newer libssh2 to fix missing libssh2_sftp_fsync (bz #999161) -* Tue Jul 30 2013 Cole Robinson - 2:1.4.2-5 -- Fix usb_handle_packet assertions (bz #981459) +* Tue Aug 20 2013 Cole Robinson - 2:1.6.0-3 +- Require newer ceph-libs to fix symbol error (bz #995883) -* Wed Jun 19 2013 Cole Robinson - 2:1.4.2-4 -- Fix build with latest libfdt +* Tue Aug 20 2013 Richard W.M. Jones - 2:1.6.0-2 +- Try to rebuild since previous i686 build was broken (RHBZ#998722). +- In build, qemu -help just to check the binary is not broken. + +* Fri Aug 16 2013 Cole Robinson - 2:1.6.0-1 +- Rebased to version 1.6.0 +- Support for live migration over RDMA +- TCG target for aarch64. +- Support for auto-convergence in live migration ("CPU stunning") +- The XHCI (USB 3.0) controller supports live migration. +- New device "nvme" provides a PCI device that implements the NVMe + standard. +- ACPI hotplug of devices behind a PCI bridge is supported + +* Sun Aug 04 2013 Dennis Gilmore - 2:1.5.2-4 +- re-enable spice support + +* Fri Aug 02 2013 Dennis Gilmore - 2:1.5.2-3 +- build without spice support to build against new libiscsi +- spice requires parts of qemu + +* Fri Aug 2 2013 Paolo Bonzini - 2:1.5.2-2 +- Rebuild for libiscsi soname bump + +* Mon Jul 29 2013 Cole Robinson - 2:1.5.2-1 +- Rebased to version 1.5.2 +- Fix mouse display with spice and latest libvirt (bz #981094) + +* Tue Jul 09 2013 Cole Robinson - 2:1.5.1-2 +- Update to work with seabios 1.7.3 + +* Fri Jun 28 2013 Cole Robinson - 2:1.5.1-1 +- Rebased to version 1.5.1 + +* Wed Jun 19 2013 Cole Robinson - 2:1.5.0-9 - Don't install conflicting binfmt handler on arm (bz #974804) +- Use upstream patch for libfdt build fix -* Tue Jun 11 2013 Cole Robinson - 2:1.4.2-3 +* Fri Jun 14 2013 Peter Robinson 2:1.5.0-8 +- Put ARM kvm bits in right sub package + +* Thu Jun 13 2013 Cole Robinson - 2:1.5.0-7 +- Fix build with both new and old fdt + +* Wed Jun 12 2013 Cole Robinson - 2:1.5.0-6 +- Fix build with rawhide libfdt + +* Tue Jun 11 2013 Cole Robinson - 2:1.5.0-5 - Fix rtl8139 + windows 7 + large transfers (bz #970240) -- Fix crash on large drag and drop file transfer w/ spice (bz #969109) -* Mon May 27 2013 Dan Horák - 2:1.4.2-2 +* Sat Jun 1 2013 Peter Robinson 2:1.5.0-4 +- build qemu-kvm on ARMv7 + +* Mon May 27 2013 Dan Horák - 2:1.5.0-3 - Install the qemu-kvm.1 man page only on arches with kvm -* Sat May 25 2013 Cole Robinson - 2:1.4.2-1 -- Update to qemu stable 1.4.2 +* Sat May 25 2013 Cole Robinson - 2:1.5.0-2 - Alias qemu-system-* man page to qemu.1 (bz #907746) - Drop execute bit on service files (bz #963917) - Conditionalize KSM service on host virt support (bz #963681) - Split out KSM package, make it not pulled in by default -* Wed May 22 2013 Alon Levy - 2:1.4.1-4 -- Backport migration cleanup (bz #962954) +* Tue May 21 2013 Cole Robinson - 2:1.5.0-1 +- Update to qemu 1.5 +- KVM for ARM support +- A native GTK+ UI with internationalization support +- Experimental VFIO support for VGA passthrough +- Support for VMware PVSCSI and VMXNET3 device emulation +- CPU hot-add support * Thu May 16 2013 Paolo Bonzini - 2:1.4.1-3 - Drop loading of vhost-net module (bz #963198) diff --git a/sources b/sources index f259a86..52b8f46 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -b3eafa033ae4b8faba584f9f141b888f qemu-1.4.2.tar.bz2 +32893941d40d052a5e649efcf06aca06 qemu-1.7.0.tar.bz2