From 2983660f65e196adaefdadc807effe9c1af85cb3 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Oct 06 2013 18:33:55 +0000 Subject: 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) --- diff --git a/0001-Fix-migration-from-qemu-kvm.patch b/0001-Fix-migration-from-qemu-kvm.patch deleted file mode 100644 index 4db56ab..0000000 --- a/0001-Fix-migration-from-qemu-kvm.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 846f71f534a6a026793eacb0c620f54eb30540a8 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Fri, 16 Aug 2013 12:14:51 -0400 -Subject: [PATCH] Fix migration from qemu-kvm - -Details are in the code comments for each change. Just lumped this together -to ease patch maintenance. - -Everything except the video memory bits can likely be dropped by Fedora 21 -time frame. Need to figure out if there's anything to upstream for the -video memory bits. ---- - hw/acpi/piix4.c | 8 ++++++- - hw/display/qxl.c | 9 ++++---- - hw/i386/pc_piix.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---- - hw/timer/i8254_common.c | 7 +++++- - 4 files changed, 74 insertions(+), 11 deletions(-) - -diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c -index c885690..e6c4c8b 100644 ---- a/hw/acpi/piix4.c -+++ b/hw/acpi/piix4.c -@@ -289,7 +289,13 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) - static const VMStateDescription vmstate_acpi = { - .name = "piix4_pm", - .version_id = 3, -- .minimum_version_id = 3, -+ /* -+ * 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 = 3, -+ .minimum_version_id = 2, - .minimum_version_id_old = 1, - .load_state_old = acpi_load_old, - .post_load = vmstate_acpi_post_load, -diff --git a/hw/display/qxl.c b/hw/display/qxl.c -index c537057..7ef3eff 100644 ---- a/hw/display/qxl.c -+++ b/hw/display/qxl.c -@@ -307,16 +307,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) -@@ -1981,7 +1979,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, OBJECT(qxl), "qxl.vrom", - qxl->rom_size); - vmstate_register_ram(&qxl->rom_bar, &qxl->pci.qdev); -@@ -2309,6 +2307,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/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 6e1e654..4fd5b6d 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -377,6 +377,24 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { - DEFAULT_MACHINE_OPTIONS, - }; - -+/* -+ * 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. -+ */ -+ - #define PC_COMPAT_1_3 \ - PC_COMPAT_1_4, \ - {\ -@@ -395,8 +413,17 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { - .driver = "e1000",\ - .property = "autonegotiation",\ - .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 = { - .name = "pc-1.3", - .desc = "Standard PC", -@@ -409,6 +436,19 @@ static QEMUMachine pc_machine_v1_3 = { - DEFAULT_MACHINE_OPTIONS, - }; - -+ -+/* -+ * 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. -+ * -+ * 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. -+ */ -+ - #define PC_COMPAT_1_2 \ - PC_COMPAT_1_3,\ - {\ -@@ -432,6 +472,10 @@ static QEMUMachine pc_machine_v1_3 = { - .property = "revision",\ - .value = stringify(3),\ - },{\ -+ .driver = "cirrus-vga",\ -+ .property = "vgamem_mb",\ -+ .value = stringify(16),\ -+ },{\ - .driver = "VGA",\ - .property = "mmio",\ - .value = "off",\ -@@ -462,25 +506,34 @@ static QEMUMachine pc_machine_v1_2 = { - },{\ - .driver = "VGA",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = stringify(16),\ - },{\ - .driver = "vmware-svga",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = stringify(16),\ - },{\ - .driver = "qxl-vga",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = stringify(16),\ - },{\ - .driver = "qxl",\ - .property = "vgamem_mb",\ -- .value = stringify(8),\ -+ .value = stringify(16),\ - },{\ - .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 = { - .name = "pc-1.1", - .desc = "Standard PC", -diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c -index 4e5bf0b..cbc00a0 100644 ---- a/hw/timer/i8254_common.c -+++ b/hw/timer/i8254_common.c -@@ -267,7 +267,12 @@ static const VMStateDescription vmstate_pit_common = { - .pre_save = pit_dispatch_pre_save, - .post_load = pit_dispatch_post_load, - .fields = (VMStateField[]) { -- VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), -+ /* 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_V(channels[0].irq_disabled, PITCommonState, 3), -+ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), - VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, - vmstate_pit_channel, PITChannelState), - VMSTATE_INT64(channels[0].next_transition_time, diff --git a/0001-block-ensure-bdrv_drain_all-works-during-bdrv_delete.patch b/0001-block-ensure-bdrv_drain_all-works-during-bdrv_delete.patch new file mode 100644 index 0000000..7268607 --- /dev/null +++ b/0001-block-ensure-bdrv_drain_all-works-during-bdrv_delete.patch @@ -0,0 +1,36 @@ +From 670599a08c052f6ef841743731a8f06d4b50ec99 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Thu, 27 Jun 2013 15:32:26 +0200 +Subject: [PATCH] block: ensure bdrv_drain_all() works during bdrv_delete() + +In bdrv_delete() make sure to call bdrv_make_anon() *after* bdrv_close() +so that the device is still seen by bdrv_drain_all() when iterating +bdrv_states. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit e1b5c52e04d04bb93546c6e37e8884889d047cb1) + +Signed-off-by: Michael Roth +--- + block.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/block.c b/block.c +index 01b66d8..d5ce8d3 100644 +--- a/block.c ++++ b/block.c +@@ -1606,11 +1606,11 @@ void bdrv_delete(BlockDriverState *bs) + assert(!bs->job); + assert(!bs->in_use); + ++ bdrv_close(bs); ++ + /* remove from list, if necessary */ + bdrv_make_anon(bs); + +- bdrv_close(bs); +- + g_free(bs); + } + diff --git a/0002-gdbstub-Fix-gdb_register_coprocessor-register-counti.patch b/0002-gdbstub-Fix-gdb_register_coprocessor-register-counti.patch new file mode 100644 index 0000000..46cb0d9 --- /dev/null +++ b/0002-gdbstub-Fix-gdb_register_coprocessor-register-counti.patch @@ -0,0 +1,96 @@ +From c0c080c5d1ce6c236ba8ab5db3a17043c665d0f6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andreas=20F=C3=A4rber?= +Date: Mon, 12 Aug 2013 18:09:47 +0200 +Subject: [PATCH] gdbstub: Fix gdb_register_coprocessor() register counting +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit a0e372f0c49ac01faeaeb73a6e8f50e8ac615f34 reorganized the register +counting for GDB. While it seems correct not to let the total number of +registers skyrocket in an SMP scenario through a static variable, the +distinction between total register count and 'g' packet register count +(last_reg vs. num_g_regs) got lost among the way. + +Fix this by introducing CPUState::gdb_num_g_regs and using that in +gdb_handle_packet(). + +Reported-by: Aneesh Kumar K.V +Cc: qemu-stable@nongnu.org (stable-1.6) +Tested-by: Aneesh Kumar K.V +Tested-by: Max Filippov +Tested-by: Peter Maydell +Signed-off-by: Andreas Färber +(cherry picked from commit 35143f0164e6933a85c7c2b8a89a040d881a9151) + +Signed-off-by: Michael Roth +--- + gdbstub.c | 6 ++++-- + include/qom/cpu.h | 2 ++ + qom/cpu.c | 2 +- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/gdbstub.c b/gdbstub.c +index 1af25a6..9d067d6 100644 +--- a/gdbstub.c ++++ b/gdbstub.c +@@ -621,6 +621,8 @@ void gdb_register_coprocessor(CPUState *cpu, + if (g_pos != s->base_reg) { + fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n" + "Expected %d got %d\n", xml, g_pos, s->base_reg); ++ } else { ++ cpu->gdb_num_g_regs = cpu->gdb_num_regs; + } + } + } +@@ -902,7 +904,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) + case 'g': + cpu_synchronize_state(s->g_cpu); + len = 0; +- for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) { ++ for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) { + reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); + len += reg_size; + } +@@ -914,7 +916,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) + registers = mem_buf; + len = strlen(p) / 2; + hextomem((uint8_t *)registers, p, len); +- for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) { ++ for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) { + reg_size = gdb_write_register(s->g_cpu, registers, addr); + len -= reg_size; + registers += reg_size; +diff --git a/include/qom/cpu.h b/include/qom/cpu.h +index 0d6e95c..3e49936 100644 +--- a/include/qom/cpu.h ++++ b/include/qom/cpu.h +@@ -152,6 +152,7 @@ struct kvm_run; + * @current_tb: Currently executing TB. + * @gdb_regs: Additional GDB registers. + * @gdb_num_regs: Number of total registers accessible to GDB. ++ * @gdb_num_g_regs: Number of registers in GDB 'g' packets. + * @next_cpu: Next CPU sharing TB cache. + * @kvm_fd: vCPU file descriptor for KVM. + * +@@ -188,6 +189,7 @@ struct CPUState { + struct TranslationBlock *current_tb; + struct GDBRegisterState *gdb_regs; + int gdb_num_regs; ++ int gdb_num_g_regs; + CPUState *next_cpu; + + int kvm_fd; +diff --git a/qom/cpu.c b/qom/cpu.c +index aa95108..e71e57b 100644 +--- a/qom/cpu.c ++++ b/qom/cpu.c +@@ -240,7 +240,7 @@ static void cpu_common_initfn(Object *obj) + CPUState *cpu = CPU(obj); + CPUClass *cc = CPU_GET_CLASS(obj); + +- cpu->gdb_num_regs = cc->gdb_num_core_regs; ++ cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs; + } + + static int64_t cpu_common_get_arch_id(CPUState *cpu) diff --git a/0002-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch b/0002-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch deleted file mode 100644 index 607826c..0000000 --- a/0002-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch +++ /dev/null @@ -1,38 +0,0 @@ -From f3e59ce7c471d3f0f1f293ecd0ef3e1797ce411f Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Sat, 31 Aug 2013 18:25:01 -0400 -Subject: [PATCH] qapi-types.py: Fix enum struct sizes on i686 - -Unlike other list types, enum wasn't adding any padding, which caused -a mismatch between the generated struct size and GenericList struct -size. More details in a678e26cbe89f7a27cbce794c2c2784571ee9d21 - -This crashed qemu if calling qmp query-tpm-types for example, which -upsets libvirt capabilities probing. Reproducer on i686: - -(sleep 5; printf '{"execute":"qmp_capabilities"}\n{"execute":"query-tpm-types"}\n') | ./i386-softmmu/qemu-system-i386 -S -nodefaults -nographic -M none -qmp stdio - -https://bugs.launchpad.net/qemu/+bug/1219207 - -Cc: qemu-stable@nongnu.org -(cherry picked from commit a9d960fb0b1bc104294ab965116a2d53038b4692) ---- - scripts/qapi-types.py | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py -index 5ee46ea..5d31b06 100644 ---- a/scripts/qapi-types.py -+++ b/scripts/qapi-types.py -@@ -51,7 +51,10 @@ def generate_fwd_enum_struct(name, members): - return mcgen(''' - typedef struct %(name)sList - { -- %(name)s value; -+ union { -+ %(name)s value; -+ uint64_t padding; -+ }; - struct %(name)sList *next; - } %(name)sList; - ''', diff --git a/0003-isapc-disable-kvmvapic.patch b/0003-isapc-disable-kvmvapic.patch deleted file mode 100644 index 1fd2899..0000000 --- a/0003-isapc-disable-kvmvapic.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 56cee96f3c71ffee457d8fbdf427c47824a12e05 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) - -Signed-off-by: Cole Robinson ---- - hw/i386/pc_piix.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 4fd5b6d..462d991 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -795,7 +795,11 @@ static QEMUMachine isapc_machine = { - .init = pc_init_isa, - .max_cpus = 1, - .compat_props = (GlobalProperty[]) { -- { /* end of list */ } -+ { -+ .driver = "apic-common", -+ .property = "vapic", -+ .value = "off", -+ }, - }, - DEFAULT_MACHINE_OPTIONS, - }; diff --git a/0003-target-ppc-fix-bit-extraction-for-FPBF-and-FPL.patch b/0003-target-ppc-fix-bit-extraction-for-FPBF-and-FPL.patch new file mode 100644 index 0000000..faf651b --- /dev/null +++ b/0003-target-ppc-fix-bit-extraction-for-FPBF-and-FPL.patch @@ -0,0 +1,40 @@ +From 52f99b02e5ff1004fb3b41846d2c34f190127456 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Thu, 15 Aug 2013 13:32:38 +0200 +Subject: [PATCH] target-ppc: fix bit extraction for FPBF and FPL + +Bit extraction for the FP BF and L field of the MTFSFI and MTFSF +instructions is wrong and doesn't match the reference manual (which +explain the bit number in big endian format). It has been broken in +commit 7d08d85645def18eac2a9d672c1868a35e0bcf79. + +This patch fixes this, which in turn fixes the problem reported by +Khem Raj about the floor() function of libm. + +Reported-by: Khem Raj +Signed-off-by: Aurelien Jarno +CC: qemu-stable@nongnu.org (1.6) +Signed-off-by: Alexander Graf +(cherry picked from commit 779f659021d1754117bce1aab9370dc22f37ae07) + +Signed-off-by: Michael Roth +--- + target-ppc/translate.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target-ppc/translate.c b/target-ppc/translate.c +index f07d70d..41f4048 100644 +--- a/target-ppc/translate.c ++++ b/target-ppc/translate.c +@@ -428,9 +428,9 @@ EXTRACT_HELPER(CRM, 12, 8); + EXTRACT_HELPER(SR, 16, 4); + + /* mtfsf/mtfsfi */ +-EXTRACT_HELPER(FPBF, 19, 3); ++EXTRACT_HELPER(FPBF, 23, 3); + EXTRACT_HELPER(FPIMM, 12, 4); +-EXTRACT_HELPER(FPL, 21, 1); ++EXTRACT_HELPER(FPL, 25, 1); + EXTRACT_HELPER(FPFLM, 17, 8); + EXTRACT_HELPER(FPW, 16, 1); + diff --git a/0004-pci-do-not-export-pci_bus_reset.patch b/0004-pci-do-not-export-pci_bus_reset.patch deleted file mode 100644 index a7fb21d..0000000 --- a/0004-pci-do-not-export-pci_bus_reset.patch +++ /dev/null @@ -1,72 +0,0 @@ -From b8decc166db51601a6ad6f1df1752e9a9dc4544c 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 - -qbus_reset_all can be used instead. There is no semantic change -because pcibus_reset returns 1 and takes care of the device -tree traversal. - -This will be necessary once the traversal is done always in -qbus_reset_all *before* invoking pcibus_reset itself. - -Tested-by: Claudio Bley -Signed-off-by: Paolo Bonzini ---- - 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 4c004f5..0389375 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -210,8 +210,9 @@ void pci_device_reset(PCIDevice *dev) - * Trigger pci bus reset under a given bus. - * To be called on RST# assert. - */ --void pci_bus_reset(PCIBus *bus) -+static int pcibus_reset(BusState *qbus) - { -+ PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus); - int i; - - for (i = 0; i < bus->nirq; i++) { -@@ -222,11 +223,6 @@ void pci_bus_reset(PCIBus *bus) - pci_device_reset(bus->devices[i]); - } - } --} -- --static int pcibus_reset(BusState *qbus) --{ -- pci_bus_reset(DO_UPCAST(PCIBus, qbus, qbus)); - - /* topology traverse is done by pci_bus_reset(). - Tell qbus/qdev walker not to traverse the tree */ -diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c -index a90671d..5d0e5ff 100644 ---- a/hw/pci/pci_bridge.c -+++ b/hw/pci/pci_bridge.c -@@ -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. */ -- pci_bus_reset(&s->sec_bus); -+ qbus_reset_all(&s->sec_bus.qbus); - } - } - -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index ccec2ba..32f1419 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -376,7 +376,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/0004-rdma-silly-ipv6-bugfix.patch b/0004-rdma-silly-ipv6-bugfix.patch new file mode 100644 index 0000000..6ee6865 --- /dev/null +++ b/0004-rdma-silly-ipv6-bugfix.patch @@ -0,0 +1,37 @@ +From 260790645e95891cb264c2d657648f43401ac915 Mon Sep 17 00:00:00 2001 +From: "Michael R. Hines" +Date: Sun, 18 Aug 2013 22:27:08 -0400 +Subject: [PATCH] rdma: silly ipv6 bugfix + +My bad - but it's very important for us to warn the user that +IPv6 is broken on RoCE in linux right now, until linux releases +a fixed version. + +Signed-off-by: Michael R. Hines +Signed-off-by: Michael Tokarev +(cherry picked from commit c89aa2f1851b08c3efa8a1070c0a6b9a36e1227f) + +Signed-off-by: Michael Roth +--- + migration-rdma.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/migration-rdma.c b/migration-rdma.c +index 3d1266f..f5e75d6 100644 +--- a/migration-rdma.c ++++ b/migration-rdma.c +@@ -920,9 +920,11 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) + ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_dst_addr, + RDMA_RESOLVE_TIMEOUT_MS); + if (!ret) { +- ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs); +- if (ret) { +- continue; ++ if (e->ai_family == AF_INET6) { ++ ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs); ++ if (ret) { ++ continue; ++ } + } + goto route; + } diff --git a/0005-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch b/0005-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch deleted file mode 100644 index a418e80..0000000 --- a/0005-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 7dbd6881f10537bf586f1eedf5a3bda2e50174ca 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 - functions - -Resetting should be done in post-order, not pre-order. However, -qdev_walk_children and qbus_walk_children do not allow this. Fix -it by adding two extra arguments to the functions. - -Tested-by: Claudio Bley -Signed-off-by: Paolo Bonzini ---- - hw/core/qdev.c | 45 +++++++++++++++++++++++++++++++++------------ - include/hw/qdev-core.h | 13 +++++++++---- - 2 files changed, 42 insertions(+), 16 deletions(-) - -diff --git a/hw/core/qdev.c b/hw/core/qdev.c -index 9190a7e..842804f 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) - { -- qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL); -+ qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); - } - - void qbus_reset_all(BusState *bus) - { -- qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL); -+ qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); - } - - void qbus_reset_all_fn(void *opaque) -@@ -343,49 +343,70 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) - return NULL; - } - --int qbus_walk_children(BusState *bus, 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) - { - BusChild *kid; - int err; - -- if (busfn) { -- err = busfn(bus, opaque); -+ if (pre_busfn) { -+ err = pre_busfn(bus, opaque); - if (err) { - return err; - } - } - - QTAILQ_FOREACH(kid, &bus->children, sibling) { -- err = qdev_walk_children(kid->child, devfn, busfn, opaque); -+ err = qdev_walk_children(kid->child, -+ pre_devfn, pre_busfn, -+ post_devfn, post_busfn, opaque); - if (err < 0) { - return err; - } - } - -+ if (post_busfn) { -+ err = post_busfn(bus, opaque); -+ if (err) { -+ return err; -+ } -+ } -+ - return 0; - } - --int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, -- qbus_walkerfn *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) - { - BusState *bus; - int err; - -- if (devfn) { -- err = devfn(dev, opaque); -+ if (pre_devfn) { -+ err = pre_devfn(dev, opaque); - if (err) { - return err; - } - } - - QLIST_FOREACH(bus, &dev->child_bus, sibling) { -- err = qbus_walk_children(bus, devfn, busfn, opaque); -+ err = qbus_walk_children(bus, pre_devfn, pre_busfn, -+ post_devfn, post_busfn, opaque); - if (err < 0) { - return err; - } - } - -+ if (post_devfn) { -+ err = post_devfn(dev, opaque); -+ if (err) { -+ return err; -+ } -+ } -+ - return 0; - } - -diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h -index 46972f4..c6c9b14 100644 ---- a/include/hw/qdev-core.h -+++ b/include/hw/qdev-core.h -@@ -270,10 +270,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/0005-scripts-qapi.py-Avoid-syntax-not-supported-by-Python.patch b/0005-scripts-qapi.py-Avoid-syntax-not-supported-by-Python.patch new file mode 100644 index 0000000..292328e --- /dev/null +++ b/0005-scripts-qapi.py-Avoid-syntax-not-supported-by-Python.patch @@ -0,0 +1,32 @@ +From d6dcfd69f8b2aa2cad79486bbadef7d51f7f4e7d Mon Sep 17 00:00:00 2001 +From: Peter Maydell +Date: Tue, 20 Aug 2013 15:50:15 +0100 +Subject: [PATCH] scripts/qapi.py: Avoid syntax not supported by Python 2.4 + +The Python "except Foo as x" syntax was only introduced in +Python 2.6, but we aim to support Python 2.4 and later. +Use the old-style "except Foo, x" syntax instead, thus +fixing configure/compile on systems with older Python. + +Signed-off-by: Peter Maydell +Signed-off-by: Luiz Capitulino +(cherry picked from commit 21e0043bada1a24ae2ba6cd0051e104c0cbf9634) + +Signed-off-by: Michael Roth +--- + scripts/qapi.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/qapi.py b/scripts/qapi.py +index 0ebea94..1069310 100644 +--- a/scripts/qapi.py ++++ b/scripts/qapi.py +@@ -161,7 +161,7 @@ class QAPISchema: + def parse_schema(fp): + try: + schema = QAPISchema(fp) +- except QAPISchemaError as e: ++ except QAPISchemaError, e: + print >>sys.stderr, e + exit(1) + diff --git a/0006-qdev-switch-reset-to-post-order.patch b/0006-qdev-switch-reset-to-post-order.patch deleted file mode 100644 index 4679fc5..0000000 --- a/0006-qdev-switch-reset-to-post-order.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 59164410b2f021d53be2ce45630647e952ccf9c2 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 - -Post-order is the only sensible direction for the reset signals. -For example, suppose pre-order is used and the parent has some data -structures that cache children state (for example a list of active -requests). When the reset method is invoked on the parent, these caches -could be in any state. - -If post-order is used, on the other hand, these will be in a known state -when the reset method is invoked on the parent. - -This change means that it is no longer possible to block the visit of -the devices, so the callback is changed to return void. This is not -a problem, because PCI was returning 1 exactly in order to achieve the -same ordering that this patch implements. - -PCI can then rely on the qdev core having sent a "reset signal" -(whatever that means) to the device, and only do the PCI-specific -initialization with the new function pci_do_device_reset, extracted -from pci_device_reset. There is no change in the operation of FLR, -which used and still uses pci_device_reset. - -Tested-by: Claudio Bley -Signed-off-by: Paolo Bonzini ---- - 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 842804f..87d7e1e 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 0389375..bbca696 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -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 Property pci_props[] = { - DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), -@@ -165,16 +165,10 @@ void pci_device_deassert_intx(PCIDevice *dev) - } - } - --/* -- * This function is called on #RST and FLR. -- * FLR if PCI_EXP_DEVCTL_BCR_FLR is set -- */ --void pci_device_reset(PCIDevice *dev) -+static void pci_do_device_reset(PCIDevice *dev) - { - int r; - -- qdev_reset_all(&dev->qdev); -- - dev->irq_state = 0; - pci_update_irq_status(dev); - pci_device_deassert_intx(dev); -@@ -207,10 +201,21 @@ void pci_device_reset(PCIDevice *dev) - } - - /* -+ * This function is called on #RST and FLR. -+ * FLR if PCI_EXP_DEVCTL_BCR_FLR is set -+ */ -+void pci_device_reset(PCIDevice *dev) -+{ -+ qdev_reset_all(&dev->qdev); -+ pci_do_device_reset(dev); -+} -+ -+/* - * Trigger pci bus reset under a given bus. -- * To be called on RST# assert. -+ * Called via qbus_reset_all on RST# assert, after the devices -+ * have been reset qdev_reset_all-ed already. - */ --static int pcibus_reset(BusState *qbus) -+static void pcibus_reset(BusState *qbus) - { - PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus); - int i; -@@ -220,13 +225,9 @@ static int pcibus_reset(BusState *qbus) - } - for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { - if (bus->devices[i]) { -- pci_device_reset(bus->devices[i]); -+ pci_do_device_reset(bus->devices[i]); - } - } -- -- /* topology traverse is done by pci_bus_reset(). -- Tell qbus/qdev walker not to traverse the tree */ -- return 1; - } - - 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 c6c9b14..89dcbad 100644 ---- a/include/hw/qdev-core.h -+++ b/include/hw/qdev-core.h -@@ -174,7 +174,7 @@ struct BusClass { - * bindings can be found at http://playground.sun.com/1275/bindings/. - */ - char *(*get_fw_dev_path)(DeviceState *dev); -- int (*reset)(BusState *bus); -+ void (*reset)(BusState *bus); - /* maximum devices allowed on the bus, 0: no limit. */ - int max_dev; - }; diff --git a/0006-usb-dev-hid-Modified-usb-tablet-category-from-Misc-t.patch b/0006-usb-dev-hid-Modified-usb-tablet-category-from-Misc-t.patch new file mode 100644 index 0000000..ed4a84b --- /dev/null +++ b/0006-usb-dev-hid-Modified-usb-tablet-category-from-Misc-t.patch @@ -0,0 +1,35 @@ +From 11b0ab70a58e3e6c06dc1fd1ea318b1c5806d955 Mon Sep 17 00:00:00 2001 +From: Marcel Apfelbaum +Date: Thu, 22 Aug 2013 20:11:36 +0300 +Subject: [PATCH] usb/dev-hid: Modified usb-tablet category from Misc to Input +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +usb-tablet device was wrongly assigned to Misc category + +Reported-by: Markus Armbruster +Cc: qemu-stable@nongnu.org +Signed-off-by: Marcel Apfelbaum +Reviewed-by: Andreas Färber +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 31efd2e883018b4c079ad082105bc161fbb3fef8) + +Signed-off-by: Michael Roth +--- + hw/usb/dev-hid.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c +index 66c6331..5956720 100644 +--- a/hw/usb/dev-hid.c ++++ b/hw/usb/dev-hid.c +@@ -658,7 +658,7 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data) + uc->product_desc = "QEMU USB Tablet"; + dc->vmsd = &vmstate_usb_ptr; + dc->props = usb_tablet_properties; +- set_bit(DEVICE_CATEGORY_MISC, dc->categories); ++ set_bit(DEVICE_CATEGORY_INPUT, dc->categories); + } + + static const TypeInfo usb_tablet_info = { diff --git a/0007-qxl-fix-local-renderer.patch b/0007-qxl-fix-local-renderer.patch deleted file mode 100644 index fa226de..0000000 --- a/0007-qxl-fix-local-renderer.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 909d4a71878f3568b6c636a07d9f4f2c97a5de12 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/display/qxl-render.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c -index 269b1a7..d34b0c4 100644 ---- a/hw/display/qxl-render.c -+++ b/hw/display/qxl-render.c -@@ -31,10 +31,6 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect) - if (is_buffer_shared(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; -@@ -104,7 +100,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( -@@ -128,6 +129,10 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) - } - dpy_gfx_replace_surface(vga->con, surface); - } -+ -+ 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/0007-scsi-Fix-scsi_bus_legacy_add_drive-scsi-generic-with.patch b/0007-scsi-Fix-scsi_bus_legacy_add_drive-scsi-generic-with.patch new file mode 100644 index 0000000..868951b --- /dev/null +++ b/0007-scsi-Fix-scsi_bus_legacy_add_drive-scsi-generic-with.patch @@ -0,0 +1,49 @@ +From 964e0d4ec52ea7400ccc69de69b05ac913bbfff8 Mon Sep 17 00:00:00 2001 +From: Markus Armbruster +Date: Fri, 23 Aug 2013 18:01:58 +0200 +Subject: [PATCH] scsi: Fix scsi_bus_legacy_add_drive() scsi-generic with + serial +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +scsi_bus_legacy_add_drive() creates either a scsi-disk or a +scsi-generic device. It sets property "serial" to argument serial +unless null. Crashes with scsi-generic, because it doesn't have such +the property. + +Only usb_msd_initfn_storage() passes non-null serial. Reproducer: + + $ qemu-system-x86_64 -nodefaults -display none -S -usb \ + -drive if=none,file=/dev/sg1,id=usb-drv0 \ + -device usb-storage,id=usb-msd0,drive=usb-drv0,serial=123 + qemu-system-x86_64: -device usb-storage,id=usb-msd0,drive=usb-drv0,serial=123: Property '.serial' not found + Aborted (core dumped) + +Fix by handling exactly like "removable": set the property only when +it exists. + +Cc: qemu-stable@nongnu.org +Reviewed-by: Andreas Färber +Signed-off-by: Markus Armbruster +Signed-off-by: Paolo Bonzini +(cherry picked from commit c24e7517ee4a98e90eee5f0f07708a1fa12326b3) + +Signed-off-by: Michael Roth +--- + hw/scsi/scsi-bus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c +index fbf9173..8fe4f4c 100644 +--- a/hw/scsi/scsi-bus.c ++++ b/hw/scsi/scsi-bus.c +@@ -224,7 +224,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, + if (object_property_find(OBJECT(dev), "removable", NULL)) { + qdev_prop_set_bit(dev, "removable", removable); + } +- if (serial) { ++ if (serial && object_property_find(OBJECT(dev), "serial", NULL)) { + qdev_prop_set_string(dev, "serial", serial); + } + if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) { diff --git a/0008-ehci-save-device-pointer-in-EHCIState.patch b/0008-ehci-save-device-pointer-in-EHCIState.patch deleted file mode 100644 index 0168d9c..0000000 --- a/0008-ehci-save-device-pointer-in-EHCIState.patch +++ /dev/null @@ -1,65 +0,0 @@ -From f0679fb95d2c1b9597b83184309e70cc3c3e3b1d Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 9 Sep 2013 10:18:17 +0200 -Subject: [PATCH] ehci: save device pointer in EHCIState - -We'll need a pointer to the actual pci/sysbus device, -stick a pointer to it into the EHCIState struct. - -https://bugzilla.redhat.com/show_bug.cgi?id=1005495 - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit adbecc89731cf3e0ae656d50ea9fa58c589c4bdc) ---- - hw/usb/hcd-ehci.c | 7 +++---- - hw/usb/hcd-ehci.h | 1 + - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c -index 010a0d0..e9fb20c 100644 ---- a/hw/usb/hcd-ehci.c -+++ b/hw/usb/hcd-ehci.c -@@ -1241,13 +1241,11 @@ static int ehci_init_transfer(EHCIPacket *p) - { - uint32_t cpage, offset, bytes, plen; - dma_addr_t page; -- USBBus *bus = &p->queue->ehci->bus; -- BusState *qbus = BUS(bus); - - cpage = get_field(p->qtd.token, QTD_TOKEN_CPAGE); - bytes = get_field(p->qtd.token, QTD_TOKEN_TBYTES); - offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK; -- qemu_sglist_init(&p->sgl, qbus->parent, 5, p->queue->ehci->as); -+ qemu_sglist_init(&p->sgl, p->queue->ehci->device, 5, p->queue->ehci->as); - - while (bytes > 0) { - if (cpage > 4) { -@@ -1486,7 +1484,7 @@ static int ehci_process_itd(EHCIState *ehci, - return -1; - } - -- qemu_sglist_init(&ehci->isgl, DEVICE(ehci), 2, ehci->as); -+ qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as); - if (off + len > 4096) { - /* transfer crosses page border */ - uint32_t len2 = off + len - 4096; -@@ -2529,6 +2527,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) - - s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s); - s->async_bh = qemu_bh_new(ehci_frame_timer, s); -+ s->device = dev; - - qemu_register_reset(ehci_reset, s); - qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); -diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h -index 15a28e8..065c9fa 100644 ---- a/hw/usb/hcd-ehci.h -+++ b/hw/usb/hcd-ehci.h -@@ -255,6 +255,7 @@ typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead; - - struct EHCIState { - USBBus bus; -+ DeviceState *device; - qemu_irq irq; - MemoryRegion mem; - AddressSpace *as; diff --git a/0008-pc-fix-regression-for-64-bit-PCI-memory.patch b/0008-pc-fix-regression-for-64-bit-PCI-memory.patch new file mode 100644 index 0000000..c2a1152 --- /dev/null +++ b/0008-pc-fix-regression-for-64-bit-PCI-memory.patch @@ -0,0 +1,116 @@ +From a73c74f63aa8f977ece88c97280a03ea9b1ca395 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Tue, 27 Aug 2013 08:37:26 +0300 +Subject: [PATCH] pc: fix regression for 64 bit PCI memory + +commit 398489018183d613306ab022653552247d93919f + pc: limit 64 bit hole to 2G by default +introduced a way for management to control +the window allocated to the 64 bit PCI hole. + +This is useful, but existing management tools do not know how to set +this property. As a result, e.g. specifying a large ivshmem device with +size > 4G is broken by default. For example this configuration no +longer works: + +-device ivshmem,size=4294967296,chardev=cfoo +-chardev socket,path=/tmp/sock,id=cfoo,server,nowait + +Fix this by detecting that hole size was not specified +and defaulting to the backwards-compatible value of 1 << 62. + +Cc: qemu-stable@nongnu.org +Cc: Igor Mammedov +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 1466cef32dd5e7ef3c6477e96d85d92302ad02e3) + +Signed-off-by: Michael Roth +--- + hw/pci-host/piix.c | 9 ++++++--- + hw/pci-host/q35.c | 8 +++++--- + include/hw/i386/pc.h | 11 ++++++++++- + 3 files changed, 21 insertions(+), 7 deletions(-) + +diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c +index dc1718f..221d82b 100644 +--- a/hw/pci-host/piix.c ++++ b/hw/pci-host/piix.c +@@ -320,6 +320,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, + PCII440FXState *f; + unsigned i; + I440FXState *i440fx; ++ uint64_t pci_hole64_size; + + dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE); + s = PCI_HOST_BRIDGE(dev); +@@ -351,13 +352,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, + pci_hole_start, pci_hole_size); + memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole); + ++ pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size); ++ + pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size, +- i440fx->pci_hole64_size); ++ pci_hole64_size); + memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64", + f->pci_address_space, + i440fx->pci_info.w64.begin, +- i440fx->pci_hole64_size); +- if (i440fx->pci_hole64_size) { ++ pci_hole64_size); ++ if (pci_hole64_size) { + memory_region_add_subregion(f->system_memory, + i440fx->pci_info.w64.begin, + &f->pci_hole_64bit); +diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c +index 12314d8..4febd24 100644 +--- a/hw/pci-host/q35.c ++++ b/hw/pci-host/q35.c +@@ -320,6 +320,7 @@ static int mch_init(PCIDevice *d) + { + int i; + MCHPCIState *mch = MCH_PCI_DEVICE(d); ++ uint64_t pci_hole64_size; + + /* setup pci memory regions */ + memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole", +@@ -329,13 +330,14 @@ static int mch_init(PCIDevice *d) + memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size, + &mch->pci_hole); + ++ pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size); + pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size, +- mch->pci_hole64_size); ++ pci_hole64_size); + memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64", + mch->pci_address_space, + mch->pci_info.w64.begin, +- mch->pci_hole64_size); +- if (mch->pci_hole64_size) { ++ pci_hole64_size); ++ if (pci_hole64_size) { + memory_region_add_subregion(mch->system_memory, + mch->pci_info.w64.begin, + &mch->pci_hole_64bit); +diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h +index f79d478..475ba9e 100644 +--- a/include/hw/i386/pc.h ++++ b/include/hw/i386/pc.h +@@ -106,7 +106,16 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, + #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start" + #define PCI_HOST_PROP_PCI_HOLE64_END "pci-hole64-end" + #define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size" +-#define DEFAULT_PCI_HOLE64_SIZE (1ULL << 31) ++#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL) ++ ++static inline uint64_t pci_host_get_hole64_size(uint64_t pci_hole64_size) ++{ ++ if (pci_hole64_size == DEFAULT_PCI_HOLE64_SIZE) { ++ return 1ULL << 62; ++ } else { ++ return pci_hole64_size; ++ } ++} + + void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start, + uint64_t pci_hole64_size); diff --git a/0009-pseries-Fix-stalls-on-hypervisor-virtual-console.patch b/0009-pseries-Fix-stalls-on-hypervisor-virtual-console.patch new file mode 100644 index 0000000..28878e7 --- /dev/null +++ b/0009-pseries-Fix-stalls-on-hypervisor-virtual-console.patch @@ -0,0 +1,45 @@ +From 3fe494efc5eb107c4c90e96df3e6131f9960f4b9 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Tue, 13 Aug 2013 14:10:04 +1000 +Subject: [PATCH] pseries: Fix stalls on hypervisor virtual console + +A number of users are reporting stalls when using the pseries +hypervisor virtual console. + +A simple test case is to paste 15 or 17 characters at a time +into the console. Pasting 15 characters at a time works fine +but pasting 17 characters hangs for a random amount of time. +Other activity (network, qemu monitor etc) unblocks it. + +If qemu-char tries to send more than 16 characters at once, +vty_can_receive returns false. At this point we have to +wait for the guest to consume that output. Everything is good +so far. + +The problem occurs when the the guest does consume the output. +We need to signal back to the qemu-char layer that we are +ready for more input. Without this we block until something +else kicks us (eg network activity). + +Signed-off-by: Anton Blanchard +Signed-off-by: Alexander Graf +(cherry picked from commit 7770b6f78a2d655e03852a5de238f5926c92be6a) + +Signed-off-by: Michael Roth +--- + hw/char/spapr_vty.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c +index a799721..9c2aef8 100644 +--- a/hw/char/spapr_vty.c ++++ b/hw/char/spapr_vty.c +@@ -47,6 +47,8 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max) + buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE]; + } + ++ qemu_chr_accept_input(dev->chardev); ++ + return n; + } + diff --git a/0010-virtio-virtqueue_get_avail_bytes-fix-desc_pa-when-lo.patch b/0010-virtio-virtqueue_get_avail_bytes-fix-desc_pa-when-lo.patch new file mode 100644 index 0000000..ed450ab --- /dev/null +++ b/0010-virtio-virtqueue_get_avail_bytes-fix-desc_pa-when-lo.patch @@ -0,0 +1,41 @@ +From 358bb0daa1ce332a18cc996fcd078a3989f77d36 Mon Sep 17 00:00:00 2001 +From: yinyin +Date: Thu, 22 Aug 2013 14:47:16 +0800 +Subject: [PATCH] virtio: virtqueue_get_avail_bytes: fix desc_pa when loop over + the indirect descriptor table + +virtqueue_get_avail_bytes: when found a indirect desc, we need loop over it. + /* loop over the indirect descriptor table */ + indirect = 1; + max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc); + num_bufs = i = 0; + desc_pa = vring_desc_addr(desc_pa, i); +But, It init i to 0, then use i to update desc_pa. so we will always get: +desc_pa = vring_desc_addr(desc_pa, 0); +the last two line should swap. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Yin Yin +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 1ae2757c6c4525c9b42f408c86818f843bad7418) + +Signed-off-by: Michael Roth +--- + hw/virtio/virtio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index f03c45d..2f1e73b 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -377,8 +377,8 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, + /* loop over the indirect descriptor table */ + indirect = 1; + max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc); +- num_bufs = i = 0; + desc_pa = vring_desc_addr(desc_pa, i); ++ num_bufs = i = 0; + } + + do { diff --git a/0011-xhci-fix-endpoint-interval-calculation.patch b/0011-xhci-fix-endpoint-interval-calculation.patch new file mode 100644 index 0000000..f408884 --- /dev/null +++ b/0011-xhci-fix-endpoint-interval-calculation.patch @@ -0,0 +1,27 @@ +From c0a5eb81b43e56569cfdb9c86fd78930b2765b96 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 28 Aug 2013 11:39:02 +0200 +Subject: [PATCH] xhci: fix endpoint interval calculation + +Cc: qemu-stable@nongnu.org +Signed-off-by: Gerd Hoffmann +(cherry picked from commit ca7162782a293f525633e5816470498dd86a51cf) + +Signed-off-by: Michael Roth +--- + hw/usb/hcd-xhci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 58c88b8..3c0ba8e 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -1257,7 +1257,7 @@ static void xhci_init_epctx(XHCIEPContext *epctx, + epctx->ring.ccs = ctx[2] & 1; + } + +- epctx->interval = 1 << (ctx[0] >> 16) & 0xff; ++ epctx->interval = 1 << ((ctx[0] >> 16) & 0xff); + } + + static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, diff --git a/0012-Revert-usb-hub-report-status-changes-only-once.patch b/0012-Revert-usb-hub-report-status-changes-only-once.patch new file mode 100644 index 0000000..04842a9 --- /dev/null +++ b/0012-Revert-usb-hub-report-status-changes-only-once.patch @@ -0,0 +1,48 @@ +From c09a4634d945df5d7e1fbc394646e78d7d713c67 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 27 Aug 2013 17:00:04 +0200 +Subject: [PATCH] Revert "usb-hub: report status changes only once" + +This reverts commit a309ee6e0a256f690760abfba44fceaa52a7c2f3. + +This isn't in line with the usb specification and adds regressions, +win7 fails to drive the usb hub for example. + +Was added because it "solved" the issue of hubs interacting badly +with the xhci host controller. Now with the root cause being fixed +in xhci (commit ) we can revert this one. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Gerd Hoffmann +(cherry picked from commit bdebd6ee81f4d849aa8541c289203e3992450db0) + +Signed-off-by: Michael Roth +--- + hw/usb/dev-hub.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c +index e865a98..4188a3c 100644 +--- a/hw/usb/dev-hub.c ++++ b/hw/usb/dev-hub.c +@@ -33,7 +33,6 @@ typedef struct USBHubPort { + USBPort port; + uint16_t wPortStatus; + uint16_t wPortChange; +- uint16_t wPortChange_reported; + } USBHubPort; + + typedef struct USBHubState { +@@ -468,11 +467,8 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket *p) + status = 0; + for(i = 0; i < NUM_PORTS; i++) { + port = &s->ports[i]; +- if (port->wPortChange && +- port->wPortChange_reported != port->wPortChange) { ++ if (port->wPortChange) + status |= (1 << (i + 1)); +- } +- port->wPortChange_reported = port->wPortChange; + } + if (status != 0) { + for(i = 0; i < n; i++) { diff --git a/0013-block-expect-errors-from-bdrv_co_is_allocated.patch b/0013-block-expect-errors-from-bdrv_co_is_allocated.patch new file mode 100644 index 0000000..85d0820 --- /dev/null +++ b/0013-block-expect-errors-from-bdrv_co_is_allocated.patch @@ -0,0 +1,149 @@ +From da4e203efa76f2d2ee0a17670c241881963d033d Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 4 Sep 2013 19:00:25 +0200 +Subject: [PATCH] block: expect errors from bdrv_co_is_allocated + +Some bdrv_is_allocated callers do not expect errors, but the fallback +in qcow2.c might make other callers trip on assertion failures or +infinite loops. + +Fix the callers to always look for errors. + +Cc: qemu-stable@nongnu.org +Reviewed-by: Eric Blake +Signed-off-by: Paolo Bonzini +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit d663640c04f2aab810915c556390211d75457704) + +Conflicts: + + block/cow.c + +*modified to avoid dependency on upstream's e641c1e8 + +Signed-off-by: Michael Roth +--- + block.c | 7 +++++-- + block/cow.c | 6 +++++- + block/qcow2.c | 4 +--- + block/stream.c | 2 +- + qemu-img.c | 16 ++++++++++++++-- + qemu-io-cmds.c | 4 ++++ + 6 files changed, 30 insertions(+), 9 deletions(-) + +diff --git a/block.c b/block.c +index d5ce8d3..8ce8b91 100644 +--- a/block.c ++++ b/block.c +@@ -1803,8 +1803,11 @@ int bdrv_commit(BlockDriverState *bs) + buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); + + for (sector = 0; sector < total_sectors; sector += n) { +- if (bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) { +- ++ ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n); ++ if (ret < 0) { ++ goto ro_cleanup; ++ } ++ if (ret) { + if (bdrv_read(bs, sector, buf, n) != 0) { + ret = -EIO; + goto ro_cleanup; +diff --git a/block/cow.c b/block/cow.c +index 1cc2e89..e1b73d6 100644 +--- a/block/cow.c ++++ b/block/cow.c +@@ -189,7 +189,11 @@ static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num, + int ret, n; + + while (nb_sectors > 0) { +- if (bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n)) { ++ ret = bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n); ++ if (ret < 0) { ++ return ret; ++ } ++ if (ret) { + ret = bdrv_pread(bs->file, + s->cow_sectors_offset + sector_num * 512, + buf, n * 512); +diff --git a/block/qcow2.c b/block/qcow2.c +index 3376901..7f7282e 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -648,13 +648,11 @@ static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs, + int ret; + + *pnum = nb_sectors; +- /* FIXME We can get errors here, but the bdrv_co_is_allocated interface +- * can't pass them on today */ + qemu_co_mutex_lock(&s->lock); + ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset); + qemu_co_mutex_unlock(&s->lock); + if (ret < 0) { +- *pnum = 0; ++ return ret; + } + + return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO); +diff --git a/block/stream.c b/block/stream.c +index 7fe9e48..4e8d177 100644 +--- a/block/stream.c ++++ b/block/stream.c +@@ -120,7 +120,7 @@ wait: + if (ret == 1) { + /* Allocated in the top, no need to copy. */ + copy = false; +- } else { ++ } else if (ret >= 0) { + /* Copy if allocated in the intermediate images. Limit to the + * known-unallocated area [sector_num, sector_num+n). */ + ret = bdrv_co_is_allocated_above(bs->backing_hd, base, +diff --git a/qemu-img.c b/qemu-img.c +index b9a848d..b01998b 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -1485,8 +1485,15 @@ static int img_convert(int argc, char **argv) + are present in both the output's and input's base images (no + need to copy them). */ + if (out_baseimg) { +- if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, +- n, &n1)) { ++ ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, ++ n, &n1); ++ if (ret < 0) { ++ error_report("error while reading metadata for sector " ++ "%" PRId64 ": %s", ++ sector_num - bs_offset, strerror(-ret)); ++ goto out; ++ } ++ if (!ret) { + sector_num += n1; + continue; + } +@@ -2076,6 +2083,11 @@ static int img_rebase(int argc, char **argv) + + /* If the cluster is allocated, we don't need to take action */ + ret = bdrv_is_allocated(bs, sector, n, &n); ++ if (ret < 0) { ++ error_report("error while reading image metadata: %s", ++ strerror(-ret)); ++ goto out; ++ } + if (ret) { + continue; + } +diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c +index ffbcf31..ffe48ad 100644 +--- a/qemu-io-cmds.c ++++ b/qemu-io-cmds.c +@@ -1829,6 +1829,10 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv) + sector_num = offset >> 9; + while (remaining) { + ret = bdrv_is_allocated(bs, sector_num, remaining, &num); ++ if (ret < 0) { ++ printf("is_allocated failed: %s\n", strerror(-ret)); ++ return 0; ++ } + sector_num += num; + remaining -= num; + if (ret) { diff --git a/0014-target-i386-fix-disassembly-with-PAE-1-PG-0.patch b/0014-target-i386-fix-disassembly-with-PAE-1-PG-0.patch new file mode 100644 index 0000000..1cbc2cd --- /dev/null +++ b/0014-target-i386-fix-disassembly-with-PAE-1-PG-0.patch @@ -0,0 +1,76 @@ +From f9fd82ee939d6ee5bff126b125020021e18ce330 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 30 Aug 2013 11:58:45 +0200 +Subject: [PATCH] target-i386: fix disassembly with PAE=1, PG=0 + +CR4.PAE=1 will not enable paging if CR0.PG=0, but the "if" chain +in x86_cpu_get_phys_page_debug says otherwise. Check CR0.PG +before everything else. + +Fixes "-d in_asm" for a code section at the beginning of OVMF. + +Signed-off-by: Paolo Bonzini +Signed-off-by: Richard Henderson +Reviewed-by: Max Filippov +(cherry picked from commit f2f8560c7a5303065a2a3207ec475dfb3a622a0e) + +Signed-off-by: Michael Roth +--- + target-i386/helper.c | 34 ++++++++++++++++------------------ + 1 file changed, 16 insertions(+), 18 deletions(-) + +diff --git a/target-i386/helper.c b/target-i386/helper.c +index bf3e2ac..7f74e5d 100644 +--- a/target-i386/helper.c ++++ b/target-i386/helper.c +@@ -894,7 +894,10 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) + uint32_t page_offset; + int page_size; + +- if (env->cr[4] & CR4_PAE_MASK) { ++ if (!(env->cr[0] & CR0_PG_MASK)) { ++ pte = addr & env->a20_mask; ++ page_size = 4096; ++ } else if (env->cr[4] & CR4_PAE_MASK) { + target_ulong pdpe_addr; + uint64_t pde, pdpe; + +@@ -952,26 +955,21 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) + } else { + uint32_t pde; + +- if (!(env->cr[0] & CR0_PG_MASK)) { +- pte = addr; +- page_size = 4096; ++ /* page directory entry */ ++ pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask; ++ pde = ldl_phys(pde_addr); ++ if (!(pde & PG_PRESENT_MASK)) ++ return -1; ++ if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { ++ pte = pde & ~0x003ff000; /* align to 4MB */ ++ page_size = 4096 * 1024; + } else { + /* page directory entry */ +- pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask; +- pde = ldl_phys(pde_addr); +- if (!(pde & PG_PRESENT_MASK)) ++ pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask; ++ pte = ldl_phys(pte_addr); ++ if (!(pte & PG_PRESENT_MASK)) + return -1; +- if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { +- pte = pde & ~0x003ff000; /* align to 4MB */ +- page_size = 4096 * 1024; +- } else { +- /* page directory entry */ +- pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask; +- pte = ldl_phys(pte_addr); +- if (!(pte & PG_PRESENT_MASK)) +- return -1; +- page_size = 4096; +- } ++ page_size = 4096; + } + pte = pte & env->a20_mask; + } diff --git a/0015-adlib-sort-offsets-in-portio-registration.patch b/0015-adlib-sort-offsets-in-portio-registration.patch new file mode 100644 index 0000000..a7b6816 --- /dev/null +++ b/0015-adlib-sort-offsets-in-portio-registration.patch @@ -0,0 +1,35 @@ +From 2ffbe03e8bc8f330581e31537190949a9aba80c3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= +Date: Wed, 14 Aug 2013 11:49:04 +0200 +Subject: [PATCH] adlib: sort offsets in portio registration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes the following assert when -device adlib is used: +ioport.c:240: portio_list_add: Assertion `pio->offset >= off_last' failed. + +Signed-off-by: Hervé Poussineau +Signed-off-by: Michael Tokarev +(cherry picked from commit 2b21fb57af305f17841d79e7e2e02ad1aec3f5ca) + +Signed-off-by: Michael Roth +--- + hw/audio/adlib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c +index 0421d47..db4a953 100644 +--- a/hw/audio/adlib.c ++++ b/hw/audio/adlib.c +@@ -284,9 +284,9 @@ static void Adlib_fini (AdlibState *s) + } + + static MemoryRegionPortio adlib_portio_list[] = { +- { 0x388, 4, 1, .read = adlib_read, .write = adlib_write, }, + { 0, 4, 1, .read = adlib_read, .write = adlib_write, }, + { 0, 2, 1, .read = adlib_read, .write = adlib_write, }, ++ { 0x388, 4, 1, .read = adlib_read, .write = adlib_write, }, + PORTIO_END_OF_LIST(), + }; + diff --git a/0016-exec-fix-writing-to-MMIO-area-with-non-power-of-two-.patch b/0016-exec-fix-writing-to-MMIO-area-with-non-power-of-two-.patch new file mode 100644 index 0000000..4e60171 --- /dev/null +++ b/0016-exec-fix-writing-to-MMIO-area-with-non-power-of-two-.patch @@ -0,0 +1,37 @@ +From 9fab8e1fe15014a4bd147eeedd2491bcfbba4e59 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 29 Jul 2013 14:27:39 +0200 +Subject: [PATCH] exec: fix writing to MMIO area with non-power-of-two length + +The problem is introduced by commit 2332616 (exec: Support 64-bit +operations in address_space_rw, 2013-07-08). Before that commit, +memory_access_size would only return 1/2/4. + +Since alignment is already handled above, reduce l to the largest +power of two that is smaller than l. + +Cc: qemu-stable@nongnu.org +Reported-by: Oleksii Shevchuk +Tested-by: Oleksii Shevchuk +Signed-off-by: Paolo Bonzini +(cherry picked from commit 098178f2749a63fbbb1a626dcc7d939d5cb2bde7) + +Signed-off-by: Michael Roth +--- + exec.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/exec.c b/exec.c +index 3ca9381..394f7e2 100644 +--- a/exec.c ++++ b/exec.c +@@ -1928,6 +1928,9 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) + if (l > access_size_max) { + l = access_size_max; + } ++ if (l & (l - 1)) { ++ l = 1 << (qemu_fls(l) - 1); ++ } + + return l; + } diff --git a/0017-virtio_pci-fix-level-interrupts-with-irqfd.patch b/0017-virtio_pci-fix-level-interrupts-with-irqfd.patch new file mode 100644 index 0000000..33e4853 --- /dev/null +++ b/0017-virtio_pci-fix-level-interrupts-with-irqfd.patch @@ -0,0 +1,38 @@ +From 1cd7138d492304a76f3b8ae89fc61e05b18205a7 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 1 Sep 2013 11:03:45 +0300 +Subject: [PATCH] virtio_pci: fix level interrupts with irqfd + +commit 62c96360ae7f2c7a8b029277fbb7cb082fdef7fd + virtio-pci: fix level interrupts +only helps systems without irqfd: on systems with irqfd support we +passed in flag requesting irqfd even when msix is disabled. + +As a result, for level interrupts we didn't install an fd handler so +unmasking an fd had no effect. + +Fix this up. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 23fe2b3f9e7df8da53ac1bc32c6875254911d7f4) + +Signed-off-by: Michael Roth +--- + hw/virtio/virtio-pci.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index d37037e..41b96ce 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -799,8 +799,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) + break; + } + +- r = virtio_pci_set_guest_notifier(d, n, assign, +- kvm_msi_via_irqfd_enabled()); ++ r = virtio_pci_set_guest_notifier(d, n, assign, with_irqfd); + if (r < 0) { + goto assign_error; + } diff --git a/0018-exec-always-use-MADV_DONTFORK.patch b/0018-exec-always-use-MADV_DONTFORK.patch new file mode 100644 index 0000000..95df5f7 --- /dev/null +++ b/0018-exec-always-use-MADV_DONTFORK.patch @@ -0,0 +1,43 @@ +From 57ea2d21ae1863fd4002b2aea8ea8db8e206d464 Mon Sep 17 00:00:00 2001 +From: Andrea Arcangeli +Date: Thu, 25 Jul 2013 12:11:15 +0200 +Subject: [PATCH] exec: always use MADV_DONTFORK + +MADV_DONTFORK prevents fork to fail with -ENOMEM if the default +overcommit heuristics decides there's too much anonymous virtual +memory allocated. If the KVM secondary MMU is synchronized with MMU +notifiers or not, doesn't make a difference in that regard. + +Secondly it's always more efficient to avoid copying the guest +physical address space in the fork child (so we avoid to mark all the +guest memory readonly in the parent and so we skip the establishment +and teardown of lots of pagetables in the child). + +In the common case we can ignore the error if MADV_DONTFORK is not +available. Leave a second invocation that errors out in the KVM path +if MMU notifiers are missing and KVM is enabled, to abort in such +case. + +Signed-off-by: Andrea Arcangeli +Tested-By: Benoit Canet +Acked-by: Paolo Bonzini +Signed-off-by: Gleb Natapov +(cherry picked from commit 3e469dbfe413c25d48321c3a19ddfae0727dc6e5) + +Signed-off-by: Michael Roth +--- + exec.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/exec.c b/exec.c +index 394f7e2..2ea8f04 100644 +--- a/exec.c ++++ b/exec.c +@@ -1172,6 +1172,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, + + qemu_ram_setup_dump(new_block->host, size); + qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE); ++ qemu_madvise(new_block->host, size, QEMU_MADV_DONTFORK); + + if (kvm_enabled()) + kvm_setup_guest_memory(new_block->host, size); diff --git a/0019-xhci-reset-port-when-disabling-slot.patch b/0019-xhci-reset-port-when-disabling-slot.patch new file mode 100644 index 0000000..a269bda --- /dev/null +++ b/0019-xhci-reset-port-when-disabling-slot.patch @@ -0,0 +1,26 @@ +From 9dbfbb89b204e098f283aca310e4d6f6651d88f4 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 28 Aug 2013 11:47:09 +0200 +Subject: [PATCH] xhci: reset port when disabling slot + +Cc: qemu-stable@nongnu.org +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 5c67dd7b4884979a2613a4702ac1ab68b0e6a16e) + +Signed-off-by: Michael Roth +--- + hw/usb/hcd-xhci.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 3c0ba8e..a6f55a1 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -2076,6 +2076,7 @@ static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid) + + xhci->slots[slotid-1].enabled = 0; + xhci->slots[slotid-1].addressed = 0; ++ xhci->slots[slotid-1].uport = NULL; + return CC_SUCCESS; + } + diff --git a/0020-usb-parallelize-usb3-streams.patch b/0020-usb-parallelize-usb3-streams.patch new file mode 100644 index 0000000..b1b63f4 --- /dev/null +++ b/0020-usb-parallelize-usb3-streams.patch @@ -0,0 +1,52 @@ +From 96b14d0db19b2b80ab3dc35d522671da82101e72 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 27 Aug 2013 15:25:24 +0200 +Subject: [PATCH] usb: parallelize usb3 streams + +usb3 bulk endpoints with streams are implicitly pipelined now, +so the requests will actually be processed in parallel. Also +allow them to complete out-of-order. + +Fixes stalls in the uas driver. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Gerd Hoffmann +(cherry picked from commit c96c41ed0d38d68a6c8b6f84751afebafeae31be) + +Signed-off-by: Michael Roth +--- + hw/usb/core.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/hw/usb/core.c b/hw/usb/core.c +index 05948ca..31960c2 100644 +--- a/hw/usb/core.c ++++ b/hw/usb/core.c +@@ -403,7 +403,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p) + p->ep->halted = false; + } + +- if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) { ++ if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) { + usb_process_one(p); + if (p->status == USB_RET_ASYNC) { + /* hcd drivers cannot handle async for isoc */ +@@ -420,7 +420,8 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p) + * When pipelining is enabled usb-devices must always return async, + * otherwise packets can complete out of order! + */ +- assert(!p->ep->pipeline || QTAILQ_EMPTY(&p->ep->queue)); ++ assert(p->stream || !p->ep->pipeline || ++ QTAILQ_EMPTY(&p->ep->queue)); + if (p->status != USB_RET_NAK) { + usb_packet_set_state(p, USB_PACKET_COMPLETE); + } +@@ -434,7 +435,7 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p) + { + USBEndpoint *ep = p->ep; + +- assert(QTAILQ_FIRST(&ep->queue) == p); ++ assert(p->stream || QTAILQ_FIRST(&ep->queue) == p); + assert(p->status != USB_RET_ASYNC && p->status != USB_RET_NAK); + + if (p->status != USB_RET_SUCCESS || diff --git a/0021-w32-Fix-access-to-host-devices-regression.patch b/0021-w32-Fix-access-to-host-devices-regression.patch new file mode 100644 index 0000000..9a0efb8 --- /dev/null +++ b/0021-w32-Fix-access-to-host-devices-regression.patch @@ -0,0 +1,86 @@ +From e8601a4e3102321d054ce3d641c03ebcd0519357 Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Sun, 1 Sep 2013 22:59:25 +0200 +Subject: [PATCH] w32: Fix access to host devices (regression) + +QEMU failed to open host devices like \\.\PhysicalDrive0 (first hard disk) +since some time (commit 8a79380b8ef1b02d2abd705dd026a18863b09020?). + +Those devices use hdev_open which did not use the latest API for options. +This resulted in a fatal runtime error: + + Block protocol 'host_device' doesn't support the option 'filename' + +Duplicate code from raw_open to fix this. + +Cc: qemu-stable@nongnu.org +Reported-by: David Brenner +Signed-off-by: Stefan Weil +Reviewed-by: Kevin Wolf +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 68dc036488dfea170627a55e6ee3dfd7f2c2063e) + +Signed-off-by: Michael Roth +--- + block/raw-win32.c | 36 +++++++++++++++++++++++++++++------- + 1 file changed, 29 insertions(+), 7 deletions(-) + +diff --git a/block/raw-win32.c b/block/raw-win32.c +index 9b5b2af..d2d2d9f 100644 +--- a/block/raw-win32.c ++++ b/block/raw-win32.c +@@ -535,13 +535,29 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags) + { + BDRVRawState *s = bs->opaque; + int access_flags, create_flags; ++ int ret = 0; + DWORD overlapped; + char device_name[64]; +- const char *filename = qdict_get_str(options, "filename"); ++ ++ Error *local_err = NULL; ++ const char *filename; ++ ++ QemuOpts *opts = qemu_opts_create_nofail(&raw_runtime_opts); ++ qemu_opts_absorb_qdict(opts, options, &local_err); ++ if (error_is_set(&local_err)) { ++ qerror_report_err(local_err); ++ error_free(local_err); ++ ret = -EINVAL; ++ goto done; ++ } ++ ++ filename = qemu_opt_get(opts, "filename"); + + if (strstart(filename, "/dev/cdrom", NULL)) { +- if (find_cdrom(device_name, sizeof(device_name)) < 0) +- return -ENOENT; ++ if (find_cdrom(device_name, sizeof(device_name)) < 0) { ++ ret = -ENOENT; ++ goto done; ++ } + filename = device_name; + } else { + /* transform drive letters into device name */ +@@ -564,11 +580,17 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags) + if (s->hfile == INVALID_HANDLE_VALUE) { + int err = GetLastError(); + +- if (err == ERROR_ACCESS_DENIED) +- return -EACCES; +- return -1; ++ if (err == ERROR_ACCESS_DENIED) { ++ ret = -EACCES; ++ } else { ++ ret = -1; ++ } ++ goto done; + } +- return 0; ++ ++done: ++ qemu_opts_del(opts); ++ return ret; + } + + static BlockDriver bdrv_host_device = { diff --git a/0022-memory-Provide-separate-handling-of-unassigned-io-po.patch b/0022-memory-Provide-separate-handling-of-unassigned-io-po.patch new file mode 100644 index 0000000..ff5c789 --- /dev/null +++ b/0022-memory-Provide-separate-handling-of-unassigned-io-po.patch @@ -0,0 +1,78 @@ +From 7ab1044eb1ac2cbc7e65769edf44ced92b85b038 Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Mon, 2 Sep 2013 18:43:30 +0200 +Subject: [PATCH] memory: Provide separate handling of unassigned io ports + accesses + +Accesses to unassigned io ports shall return -1 on read and be ignored +on write. Ensure these properties via dedicated ops, decoupling us from +the memory core's handling of unassigned accesses. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Jan Kiszka +Signed-off-by: Paolo Bonzini +(cherry picked from commit 3bb28b7208b349e7a1b326e3c6ef9efac1d462bf) + +Signed-off-by: Michael Roth +--- + exec.c | 3 ++- + include/exec/ioport.h | 4 ++++ + ioport.c | 16 ++++++++++++++++ + 3 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/exec.c b/exec.c +index 2ea8f04..08eecb3 100644 +--- a/exec.c ++++ b/exec.c +@@ -1821,7 +1821,8 @@ static void memory_map_init(void) + address_space_init(&address_space_memory, system_memory, "memory"); + + system_io = g_malloc(sizeof(*system_io)); +- memory_region_init(system_io, NULL, "io", 65536); ++ memory_region_init_io(system_io, NULL, &unassigned_io_ops, NULL, "io", ++ 65536); + address_space_init(&address_space_io, system_io, "I/O"); + + memory_listener_register(&core_memory_listener, &address_space_memory); +diff --git a/include/exec/ioport.h b/include/exec/ioport.h +index bdd4e96..b3848be 100644 +--- a/include/exec/ioport.h ++++ b/include/exec/ioport.h +@@ -45,6 +45,10 @@ typedef struct MemoryRegionPortio { + + #define PORTIO_END_OF_LIST() { } + ++#ifndef CONFIG_USER_ONLY ++extern const MemoryRegionOps unassigned_io_ops; ++#endif ++ + void cpu_outb(pio_addr_t addr, uint8_t val); + void cpu_outw(pio_addr_t addr, uint16_t val); + void cpu_outl(pio_addr_t addr, uint32_t val); +diff --git a/ioport.c b/ioport.c +index 79b7f1a..707cce8 100644 +--- a/ioport.c ++++ b/ioport.c +@@ -44,6 +44,22 @@ typedef struct MemoryRegionPortioList { + MemoryRegionPortio ports[]; + } MemoryRegionPortioList; + ++static uint64_t unassigned_io_read(void *opaque, hwaddr addr, unsigned size) ++{ ++ return -1ULL; ++} ++ ++static void unassigned_io_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned size) ++{ ++} ++ ++const MemoryRegionOps unassigned_io_ops = { ++ .read = unassigned_io_read, ++ .write = unassigned_io_write, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ + void cpu_outb(pio_addr_t addr, uint8_t val) + { + LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val); diff --git a/0023-Revert-memory-Return-1-again-on-reads-from-unsigned-.patch b/0023-Revert-memory-Return-1-again-on-reads-from-unsigned-.patch new file mode 100644 index 0000000..3086e82 --- /dev/null +++ b/0023-Revert-memory-Return-1-again-on-reads-from-unsigned-.patch @@ -0,0 +1,34 @@ +From 2a93d3dd32386c3522cfa2ee60c9e06a298d1f52 Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Mon, 2 Sep 2013 18:43:31 +0200 +Subject: [PATCH] Revert "memory: Return -1 again on reads from unsigned + regions" + +This reverts commit 9b8c69243585a32d14b9bb9fcd52c37b0b5a1b71. + +The commit was wrong: We only return -1 on invalid accesses, not on +valid but unbacked ones. This broke various corner cases. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Jan Kiszka +Signed-off-by: Paolo Bonzini +(cherry picked from commit 68a7439a150d6b4da99082ab454b9328b151bc25) + +Signed-off-by: Michael Roth +--- + memory.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/memory.c b/memory.c +index 886f838..5a10fd0 100644 +--- a/memory.c ++++ b/memory.c +@@ -872,7 +872,7 @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, + if (current_cpu != NULL) { + cpu_unassigned_access(current_cpu, addr, false, false, 0, size); + } +- return -1ULL; ++ return 0; + } + + static void unassigned_mem_write(void *opaque, hwaddr addr, diff --git a/0024-exec-check-offset_within_address_space-for-register-.patch b/0024-exec-check-offset_within_address_space-for-register-.patch new file mode 100644 index 0000000..590c09b --- /dev/null +++ b/0024-exec-check-offset_within_address_space-for-register-.patch @@ -0,0 +1,40 @@ +From 1110014801d368388bca2ed7c28aa695560c4991 Mon Sep 17 00:00:00 2001 +From: Hu Tao +Date: Thu, 29 Aug 2013 18:21:16 +0800 +Subject: [PATCH] exec: check offset_within_address_space for register subpage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If offset_within_address_space falls in a page, then we register a +subpage. So check offset_within_address_space rather than +offset_within_region. + +Cc: qemu-stable@nongnu.org +Cc: Paolo Bonzini +Cc: Richard Henderson +Cc: "Andreas Färber" +Cc: Peter Maydell +Cc: Blue Swirl +Signed-off-by: Hu Tao +Signed-off-by: Paolo Bonzini +(cherry picked from commit 88266249701032211c1d7449460d063fbc01bf12) + +Signed-off-by: Michael Roth +--- + exec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/exec.c b/exec.c +index 08eecb3..f6674e5 100644 +--- a/exec.c ++++ b/exec.c +@@ -869,7 +869,7 @@ static void mem_add(MemoryListener *listener, MemoryRegionSection *section) + now = remain; + if (int128_lt(remain.size, page_size)) { + register_subpage(d, &now); +- } else if (remain.offset_within_region & ~TARGET_PAGE_MASK) { ++ } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) { + now.size = page_size; + register_subpage(d, &now); + } else { diff --git a/0025-ne2000-mark-I-O-as-LITTLE_ENDIAN.patch b/0025-ne2000-mark-I-O-as-LITTLE_ENDIAN.patch new file mode 100644 index 0000000..b96e6e5 --- /dev/null +++ b/0025-ne2000-mark-I-O-as-LITTLE_ENDIAN.patch @@ -0,0 +1,35 @@ +From a1991d05d37ac9054d772b32d8fac70bc31be81a Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Mon, 2 Sep 2013 13:10:34 +0200 +Subject: [PATCH] ne2000: mark I/O as LITTLE_ENDIAN + +Now that the memory subsystem is propagating the endianness correctly, +the ne2000 device should have its I/O ports marked as LITTLE_ENDIAN, as +PCI devices are little endian. + +This makes the ne2000 NIC to work again on PowerPC. + +Cc: qemu-stable@nongnu.org +Cc: Stefan Hajnoczi +Signed-off-by: Aurelien Jarno +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 45d883dcf208160e2db308d1b368beb74f37dc7e) + +Signed-off-by: Michael Roth +--- + hw/net/ne2000.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c +index 31afd28..c961258 100644 +--- a/hw/net/ne2000.c ++++ b/hw/net/ne2000.c +@@ -693,7 +693,7 @@ static void ne2000_write(void *opaque, hwaddr addr, + static const MemoryRegionOps ne2000_ops = { + .read = ne2000_read, + .write = ne2000_write, +- .endianness = DEVICE_NATIVE_ENDIAN, ++ .endianness = DEVICE_LITTLE_ENDIAN, + }; + + /***********************************************************/ diff --git a/0026-ehci-save-device-pointer-in-EHCIState.patch b/0026-ehci-save-device-pointer-in-EHCIState.patch new file mode 100644 index 0000000..81eae5c --- /dev/null +++ b/0026-ehci-save-device-pointer-in-EHCIState.patch @@ -0,0 +1,67 @@ +From b6d163fdd8131285a01fe46e6afdba727e4df9ca Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 9 Sep 2013 10:18:17 +0200 +Subject: [PATCH] ehci: save device pointer in EHCIState + +We'll need a pointer to the actual pci/sysbus device, +stick a pointer to it into the EHCIState struct. + +https://bugzilla.redhat.com/show_bug.cgi?id=1005495 + +Signed-off-by: Gerd Hoffmann +(cherry picked from commit adbecc89731cf3e0ae656d50ea9fa58c589c4bdc) + +Signed-off-by: Michael Roth +--- + hw/usb/hcd-ehci.c | 7 +++---- + hw/usb/hcd-ehci.h | 1 + + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c +index 010a0d0..e9fb20c 100644 +--- a/hw/usb/hcd-ehci.c ++++ b/hw/usb/hcd-ehci.c +@@ -1241,13 +1241,11 @@ static int ehci_init_transfer(EHCIPacket *p) + { + uint32_t cpage, offset, bytes, plen; + dma_addr_t page; +- USBBus *bus = &p->queue->ehci->bus; +- BusState *qbus = BUS(bus); + + cpage = get_field(p->qtd.token, QTD_TOKEN_CPAGE); + bytes = get_field(p->qtd.token, QTD_TOKEN_TBYTES); + offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK; +- qemu_sglist_init(&p->sgl, qbus->parent, 5, p->queue->ehci->as); ++ qemu_sglist_init(&p->sgl, p->queue->ehci->device, 5, p->queue->ehci->as); + + while (bytes > 0) { + if (cpage > 4) { +@@ -1486,7 +1484,7 @@ static int ehci_process_itd(EHCIState *ehci, + return -1; + } + +- qemu_sglist_init(&ehci->isgl, DEVICE(ehci), 2, ehci->as); ++ qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as); + if (off + len > 4096) { + /* transfer crosses page border */ + uint32_t len2 = off + len - 4096; +@@ -2529,6 +2527,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) + + s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s); + s->async_bh = qemu_bh_new(ehci_frame_timer, s); ++ s->device = dev; + + qemu_register_reset(ehci_reset, s); + qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); +diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h +index 15a28e8..065c9fa 100644 +--- a/hw/usb/hcd-ehci.h ++++ b/hw/usb/hcd-ehci.h +@@ -255,6 +255,7 @@ typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead; + + struct EHCIState { + USBBus bus; ++ DeviceState *device; + qemu_irq irq; + MemoryRegion mem; + AddressSpace *as; diff --git a/0027-qxl-fix-local-renderer.patch b/0027-qxl-fix-local-renderer.patch new file mode 100644 index 0000000..fb9eeaf --- /dev/null +++ b/0027-qxl-fix-local-renderer.patch @@ -0,0 +1,67 @@ +From dc0973b5883df7d822b285119691ade8c84dda9c 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) + +Signed-off-by: Michael Roth +--- + hw/display/qxl-render.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c +index 269b1a7..d34b0c4 100644 +--- a/hw/display/qxl-render.c ++++ b/hw/display/qxl-render.c +@@ -31,10 +31,6 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect) + if (is_buffer_shared(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; +@@ -104,7 +100,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( +@@ -128,6 +129,10 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) + } + dpy_gfx_replace_surface(vga->con, surface); + } ++ ++ 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/0028-pc-Initializing-ram_memory-under-Xen.patch b/0028-pc-Initializing-ram_memory-under-Xen.patch new file mode 100644 index 0000000..4d8c0b7 --- /dev/null +++ b/0028-pc-Initializing-ram_memory-under-Xen.patch @@ -0,0 +1,107 @@ +From 755ec4ca0f92188458ad7ca549a75161cbdcf6ff Mon Sep 17 00:00:00 2001 +From: Anthony PERARD +Date: Mon, 9 Sep 2013 16:15:52 +0000 +Subject: [PATCH] pc: Initializing ram_memory under Xen. + +Signed-off-by: Anthony PERARD +Signed-off-by: Stefano Stabellini +Acked-by: Michael S. Tsirkin +CC: qemu-stable@nongnu.org +(cherry picked from commit 04d7bad8a4fb23e6d9af9d06ce3ddc28a251d94d) + +Signed-off-by: Michael Roth +--- + hw/i386/pc_piix.c | 2 +- + include/hw/xen/xen.h | 4 +--- + xen-all.c | 7 ++++--- + xen-stub.c | 2 +- + 4 files changed, 7 insertions(+), 8 deletions(-) + +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index 6e1e654..3df2ff9 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -93,7 +93,7 @@ static void pc_init1(MemoryRegion *system_memory, + FWCfgState *fw_cfg = NULL; + PcGuestInfo *guest_info; + +- if (xen_enabled() && xen_hvm_init() != 0) { ++ if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) { + fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); + exit(1); + } +diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h +index 6d42dd1..e1f88bf 100644 +--- a/include/hw/xen/xen.h ++++ b/include/hw/xen/xen.h +@@ -37,17 +37,15 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level); + qemu_irq *xen_interrupt_controller_init(void); + + int xen_init(void); +-int xen_hvm_init(void); ++int xen_hvm_init(MemoryRegion **ram_memory); + void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); + + #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) +-struct MemoryRegion; + void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, + struct MemoryRegion *mr); + void xen_modified_memory(ram_addr_t start, ram_addr_t length); + #endif + +-struct MemoryRegion; + void xen_register_framebuffer(struct MemoryRegion *mr); + + #if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400 +diff --git a/xen-all.c b/xen-all.c +index 21246e0..e1d0694 100644 +--- a/xen-all.c ++++ b/xen-all.c +@@ -154,7 +154,7 @@ qemu_irq *xen_interrupt_controller_init(void) + + /* Memory Ops */ + +-static void xen_ram_init(ram_addr_t ram_size) ++static void xen_ram_init(ram_addr_t ram_size, MemoryRegion **ram_memory_p) + { + MemoryRegion *sysmem = get_system_memory(); + ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; +@@ -168,6 +168,7 @@ static void xen_ram_init(ram_addr_t ram_size) + block_len += HVM_BELOW_4G_MMIO_LENGTH; + } + memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len); ++ *ram_memory_p = &ram_memory; + vmstate_register_ram_global(&ram_memory); + + if (ram_size >= HVM_BELOW_4G_RAM_END) { +@@ -1059,7 +1060,7 @@ static void xen_read_physmap(XenIOState *state) + free(entries); + } + +-int xen_hvm_init(void) ++int xen_hvm_init(MemoryRegion **ram_memory) + { + int i, rc; + unsigned long ioreq_pfn; +@@ -1134,7 +1135,7 @@ int xen_hvm_init(void) + + /* Init RAM management */ + xen_map_cache_init(xen_phys_offset_to_gaddr, state); +- xen_ram_init(ram_size); ++ xen_ram_init(ram_size, ram_memory); + + qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state); + +diff --git a/xen-stub.c b/xen-stub.c +index 47c8e73..ad189a6 100644 +--- a/xen-stub.c ++++ b/xen-stub.c +@@ -64,7 +64,7 @@ void xen_modified_memory(ram_addr_t start, ram_addr_t length) + { + } + +-int xen_hvm_init(void) ++int xen_hvm_init(MemoryRegion **ram_memory) + { + return 0; + } diff --git a/0029-pc_q35-Initialize-Xen.patch b/0029-pc_q35-Initialize-Xen.patch new file mode 100644 index 0000000..23eb4e4 --- /dev/null +++ b/0029-pc_q35-Initialize-Xen.patch @@ -0,0 +1,31 @@ +From 41900b0857df9bd33e465a6c72d7a3072dc448f4 Mon Sep 17 00:00:00 2001 +From: Anthony PERARD +Date: Mon, 9 Sep 2013 16:15:53 +0000 +Subject: [PATCH] pc_q35: Initialize Xen. + +Signed-off-by: Anthony PERARD +Signed-off-by: Stefano Stabellini +Acked-by: Michael S. Tsirkin +(cherry picked from commit 254c12825f93f405658ca3366cd34f8a8ad23511) + +Signed-off-by: Michael Roth +--- + hw/i386/pc_q35.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 10e770e..dd13130 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -81,6 +81,11 @@ static void pc_q35_init(QEMUMachineInitArgs *args) + DeviceState *icc_bridge; + PcGuestInfo *guest_info; + ++ if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) { ++ fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); ++ exit(1); ++ } ++ + icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); + object_property_add_child(qdev_get_machine(), "icc-bridge", + OBJECT(icc_bridge), NULL); diff --git a/0030-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch b/0030-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch new file mode 100644 index 0000000..17578b2 --- /dev/null +++ b/0030-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch @@ -0,0 +1,44 @@ +From 8b4b3a71fd35d67c5c30652a120c0a59dfab7182 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Sat, 31 Aug 2013 18:36:17 -0400 +Subject: [PATCH] qapi-types.py: Fix enum struct sizes on i686 + +Unlike other list types, enum wasn't adding any padding, which caused +a mismatch between the generated struct size and GenericList struct +size. More details in a678e26cbe89f7a27cbce794c2c2784571ee9d21 + +This crashed qemu if calling qmp query-tpm-types for example, which +upsets libvirt capabilities probing. Reproducer on i686: + +(sleep 5; printf '{"execute":"qmp_capabilities"}\n{"execute":"query-tpm-types"}\n') | ./i386-softmmu/qemu-system-i386 -S -nodefaults -nographic -M none -qmp stdio + +https://bugs.launchpad.net/qemu/+bug/1219207 + +Cc: qemu-stable@nongnu.org +Signed-off-by: Cole Robinson +Reviewed-by: Eric Blake +Tested-by: Richard W.M. Jones +Signed-off-by: Luiz Capitulino +(cherry picked from commit 02dc4bf5684d3fb46786fab2ecff98214b1df9fe) + +Signed-off-by: Michael Roth +--- + scripts/qapi-types.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py +index 5ee46ea..5d31b06 100644 +--- a/scripts/qapi-types.py ++++ b/scripts/qapi-types.py +@@ -51,7 +51,10 @@ def generate_fwd_enum_struct(name, members): + return mcgen(''' + typedef struct %(name)sList + { +- %(name)s value; ++ union { ++ %(name)s value; ++ uint64_t padding; ++ }; + struct %(name)sList *next; + } %(name)sList; + ''', diff --git a/0031-pcnet-pci-mark-I-O-and-MMIO-as-LITTLE_ENDIAN.patch b/0031-pcnet-pci-mark-I-O-and-MMIO-as-LITTLE_ENDIAN.patch new file mode 100644 index 0000000..4e57504 --- /dev/null +++ b/0031-pcnet-pci-mark-I-O-and-MMIO-as-LITTLE_ENDIAN.patch @@ -0,0 +1,45 @@ +From 76f698948781a148d336ff9032159f6c7c9eccd2 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Wed, 28 Aug 2013 14:17:39 +0200 +Subject: [PATCH] pcnet-pci: mark I/O and MMIO as LITTLE_ENDIAN + +Now that the memory subsystem is propagating the endianness correctly, +the pcnet-pci device should have its I/O ports and MMIO memory marked +as LITTLE_ENDIAN, as PCI devices are little endian. + +This makes the pcnet-pci NIC to work again on big endian MIPS Malta +(default NIC). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Aurelien Jarno +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit a26405b350c0d31d5ef53f3b459aeb6eaaf50db0) + +Signed-off-by: Michael Roth +--- + hw/net/pcnet-pci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c +index 2c2301c..23fc33c 100644 +--- a/hw/net/pcnet-pci.c ++++ b/hw/net/pcnet-pci.c +@@ -134,7 +134,7 @@ static void pcnet_ioport_write(void *opaque, hwaddr addr, + static const MemoryRegionOps pcnet_io_ops = { + .read = pcnet_ioport_read, + .write = pcnet_ioport_write, +- .endianness = DEVICE_NATIVE_ENDIAN, ++ .endianness = DEVICE_LITTLE_ENDIAN, + }; + + static void pcnet_mmio_writeb(void *opaque, hwaddr addr, uint32_t val) +@@ -256,7 +256,7 @@ static const MemoryRegionOps pcnet_mmio_ops = { + .read = { pcnet_mmio_readb, pcnet_mmio_readw, pcnet_mmio_readl }, + .write = { pcnet_mmio_writeb, pcnet_mmio_writew, pcnet_mmio_writel }, + }, +- .endianness = DEVICE_NATIVE_ENDIAN, ++ .endianness = DEVICE_LITTLE_ENDIAN, + }; + + static void pci_physical_memory_write(void *dma_opaque, hwaddr addr, diff --git a/0032-chardev-fix-pty_chr_timer.patch b/0032-chardev-fix-pty_chr_timer.patch new file mode 100644 index 0000000..d318063 --- /dev/null +++ b/0032-chardev-fix-pty_chr_timer.patch @@ -0,0 +1,52 @@ +From 4b5b4721464495fe76fe6e2e033cbb61dce78eef Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 22 Aug 2013 11:43:58 +0200 +Subject: [PATCH] chardev: fix pty_chr_timer + +pty_chr_timer first calls pty_chr_update_read_handler(), then clears +timer_tag (because it is a one-shot timer). This is the wrong order +though. pty_chr_update_read_handler might re-arm time timer, and the +new timer_tag gets overwitten in that case. + +This leads to crashes when unplugging a pty chardev: pty_chr_close +thinks no timer is running -> timer isn't canceled -> pty_chr_timer gets +called with stale CharDevState -> BOOM. + +This patch fixes the ordering. +Kill the pointless goto while being at it. + +https://bugzilla.redhat.com/show_bug.cgi?id=994414 + +Cc: qemu-stable@nongnu.org +Signed-off-by: Gerd Hoffmann +(cherry picked from commit b0d768c35e08d2057b63e8e77e7a513c447199fa) + +Signed-off-by: Michael Roth +--- + qemu-char.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/qemu-char.c b/qemu-char.c +index 1be1cf6..1621fbd 100644 +--- a/qemu-char.c ++++ b/qemu-char.c +@@ -1026,15 +1026,11 @@ static gboolean pty_chr_timer(gpointer opaque) + struct CharDriverState *chr = opaque; + PtyCharDriver *s = chr->opaque; + +- if (s->connected) { +- goto out; +- } +- +- /* Next poll ... */ +- pty_chr_update_read_handler(chr); +- +-out: + s->timer_tag = 0; ++ if (!s->connected) { ++ /* Next poll ... */ ++ pty_chr_update_read_handler(chr); ++ } + return FALSE; + } + diff --git a/0033-kvmvapic-Catch-invalid-ROM-size.patch b/0033-kvmvapic-Catch-invalid-ROM-size.patch new file mode 100644 index 0000000..88f4018 --- /dev/null +++ b/0033-kvmvapic-Catch-invalid-ROM-size.patch @@ -0,0 +1,59 @@ +From 50b31e80525d03ef406a8c9f55ff2ae1655a3b66 Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Tue, 3 Sep 2013 18:08:50 +0200 +Subject: [PATCH] kvmvapic: Catch invalid ROM size + +If not caught early, a zero-length ROM will cause a NULL-pointer access +later on in patch_hypercalls when allocating a zero-length ROM copy and +trying to read from it. + +CC: qemu-stable@nongnu.org +Signed-off-by: Jan Kiszka +Signed-off-by: Paolo Bonzini +(cherry picked from commit 18e5eec4db96a00907eb588a2b803401637c7f67) + +Signed-off-by: Michael Roth +--- + hw/i386/kvmvapic.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c +index 15beb80..7ac0fe1 100644 +--- a/hw/i386/kvmvapic.c ++++ b/hw/i386/kvmvapic.c +@@ -578,7 +578,7 @@ static int patch_hypercalls(VAPICROMState *s) + * enable write access to the option ROM so that variables can be updated by + * the guest. + */ +-static void vapic_map_rom_writable(VAPICROMState *s) ++static int vapic_map_rom_writable(VAPICROMState *s) + { + hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK; + MemoryRegionSection section; +@@ -599,6 +599,9 @@ static void vapic_map_rom_writable(VAPICROMState *s) + /* read ROM size from RAM region */ + ram = memory_region_get_ram_ptr(section.mr); + rom_size = ram[rom_paddr + 2] * ROM_BLOCK_SIZE; ++ if (rom_size == 0) { ++ return -1; ++ } + s->rom_size = rom_size; + + /* We need to round to avoid creating subpages +@@ -612,11 +615,15 @@ static void vapic_map_rom_writable(VAPICROMState *s) + memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000); + s->rom_mapped_writable = true; + memory_region_unref(section.mr); ++ ++ return 0; + } + + static int vapic_prepare(VAPICROMState *s) + { +- vapic_map_rom_writable(s); ++ if (vapic_map_rom_writable(s) < 0) { ++ return -1; ++ } + + if (patch_hypercalls(s) < 0) { + return -1; diff --git a/0034-kvmvapic-Enter-inactive-state-on-hardware-reset.patch b/0034-kvmvapic-Enter-inactive-state-on-hardware-reset.patch new file mode 100644 index 0000000..0ebb354 --- /dev/null +++ b/0034-kvmvapic-Enter-inactive-state-on-hardware-reset.patch @@ -0,0 +1,34 @@ +From 7ea8a3c12aa49efc8f503a019dd764f8a0add2cb Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Tue, 3 Sep 2013 18:08:51 +0200 +Subject: [PATCH] kvmvapic: Enter inactive state on hardware reset + +ROM layout may change after reset of devices are hotplugged, so we have +to pick up the physical address again when the ROM is initialized. This +is best achieved by resetting the state to INACTIVE. + +CC: qemu-stable@nongnu.org +Signed-off-by: Jan Kiszka +Signed-off-by: Paolo Bonzini +(cherry picked from commit c056bc3f3464cfae1c94b7dd633d3ec13b13b655) + +Signed-off-by: Michael Roth +--- + hw/i386/kvmvapic.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c +index 7ac0fe1..f2e335d 100644 +--- a/hw/i386/kvmvapic.c ++++ b/hw/i386/kvmvapic.c +@@ -510,9 +510,7 @@ static void vapic_reset(DeviceState *dev) + { + VAPICROMState *s = VAPIC(dev); + +- if (s->state == VAPIC_ACTIVE) { +- s->state = VAPIC_STANDBY; +- } ++ s->state = VAPIC_INACTIVE; + vapic_enable_tpr_reporting(false); + } + diff --git a/0035-kvmvapic-Clear-also-physical-ROM-address-when-enteri.patch b/0035-kvmvapic-Clear-also-physical-ROM-address-when-enteri.patch new file mode 100644 index 0000000..a0d029f --- /dev/null +++ b/0035-kvmvapic-Clear-also-physical-ROM-address-when-enteri.patch @@ -0,0 +1,39 @@ +From 5d2de77798cacf1dadf6a4211972473e057cc6e5 Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Tue, 3 Sep 2013 18:08:52 +0200 +Subject: [PATCH] kvmvapic: Clear also physical ROM address when entering + INACTIVE state + +To avoid misinterpreting INACTIVE after migration as old qemu-kvm's +STANDBY, also clear rom_state_paddr when going back to this state. + +CC: qemu-stable@nongnu.org +Signed-off-by: Jan Kiszka +Signed-off-by: Paolo Bonzini +(cherry picked from commit 4357930b8a7d2fcff2d8121ec518117428a781e7) + +Signed-off-by: Michael Roth +--- + hw/i386/kvmvapic.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c +index f2e335d..cf6c714 100644 +--- a/hw/i386/kvmvapic.c ++++ b/hw/i386/kvmvapic.c +@@ -511,6 +511,7 @@ static void vapic_reset(DeviceState *dev) + VAPICROMState *s = VAPIC(dev); + + s->state = VAPIC_INACTIVE; ++ s->rom_state_paddr = 0; + vapic_enable_tpr_reporting(false); + } + +@@ -664,6 +665,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data, + } + if (vapic_prepare(s) < 0) { + s->state = VAPIC_INACTIVE; ++ s->rom_state_paddr = 0; + break; + } + break; diff --git a/0036-tci-Fix-qemu-alpha-on-32-bit-hosts-wrong-assertions.patch b/0036-tci-Fix-qemu-alpha-on-32-bit-hosts-wrong-assertions.patch new file mode 100644 index 0000000..f458952 --- /dev/null +++ b/0036-tci-Fix-qemu-alpha-on-32-bit-hosts-wrong-assertions.patch @@ -0,0 +1,125 @@ +From 5c20c1ffe791ca29840fd9607ea034ea24ad7bdd Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Thu, 12 Sep 2013 20:17:50 +0200 +Subject: [PATCH] tci: Fix qemu-alpha on 32 bit hosts (wrong assertions) + +Debian busybox-static for alpha has a load address of 0x0000000120000000 +which is mapped to 0x0000000020000000 for 32 bit hosts. + +qemu-alpha uses the TCG opcodes qemu_ld32, qemu_ld64, qemu_st32 and +qemu_st64 which all raise the assertion (taddr == host_addr). + +Remove all assertions of this type because they are either wrong or +unnecessary (when sizeof(tcg_target_ulong) >= sizeof(target_ulong)). + +Cc: qemu-stable +Signed-off-by: Stefan Weil +Reviewed-by: Richard Henderson +Signed-off-by: Michael Tokarev +(cherry picked from commit 07ac4dc5db22a31e47b149abdbc5ea99013cf4de) + +Signed-off-by: Michael Roth +--- + tci.c | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/tci.c b/tci.c +index c742c8d..af58576 100644 +--- a/tci.c ++++ b/tci.c +@@ -1085,7 +1085,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp8 = *(uint8_t *)(host_addr + GUEST_BASE); + #endif + tci_write_reg8(t0, tmp8); +@@ -1097,7 +1096,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp8 = *(uint8_t *)(host_addr + GUEST_BASE); + #endif + tci_write_reg8s(t0, tmp8); +@@ -1109,7 +1107,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE)); + #endif + tci_write_reg16(t0, tmp16); +@@ -1121,7 +1118,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE)); + #endif + tci_write_reg16s(t0, tmp16); +@@ -1134,7 +1130,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE)); + #endif + tci_write_reg32(t0, tmp32); +@@ -1146,7 +1141,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE)); + #endif + tci_write_reg32s(t0, tmp32); +@@ -1159,7 +1153,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE)); + #endif + tci_write_reg32(t0, tmp32); +@@ -1174,7 +1167,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + tmp64 = helper_ldq_mmu(env, taddr, tci_read_i(&tb_ptr)); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + tmp64 = tswap64(*(uint64_t *)(host_addr + GUEST_BASE)); + #endif + tci_write_reg(t0, tmp64); +@@ -1190,7 +1182,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + helper_stb_mmu(env, taddr, t0, t2); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + *(uint8_t *)(host_addr + GUEST_BASE) = t0; + #endif + break; +@@ -1202,7 +1193,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + helper_stw_mmu(env, taddr, t0, t2); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + *(uint16_t *)(host_addr + GUEST_BASE) = tswap16(t0); + #endif + break; +@@ -1214,7 +1204,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + helper_stl_mmu(env, taddr, t0, t2); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + *(uint32_t *)(host_addr + GUEST_BASE) = tswap32(t0); + #endif + break; +@@ -1226,7 +1215,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) + helper_stq_mmu(env, taddr, tmp64, t2); + #else + host_addr = (tcg_target_ulong)taddr; +- assert(taddr == host_addr); + *(uint64_t *)(host_addr + GUEST_BASE) = tswap64(tmp64); + #endif + break; diff --git a/0037-blockdev-do-not-default-cache.no-flush-to-true.patch b/0037-blockdev-do-not-default-cache.no-flush-to-true.patch new file mode 100644 index 0000000..c7fb6c9 --- /dev/null +++ b/0037-blockdev-do-not-default-cache.no-flush-to-true.patch @@ -0,0 +1,33 @@ +From aeab582580fa057dbe646fc3277570af6a8d5ce8 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 19 Sep 2013 18:48:53 +0200 +Subject: [PATCH] blockdev: do not default cache.no-flush to true + +That's why all my VMs were so fast lately. :) + +This changed in 1.6.0 by mistake in patch 29c4e2b (blockdev: Split up +'cache' option, 2013-07-18). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 1df6fa4bc6754a170cf511a78e2e6fef84eb5228) + +Signed-off-by: Michael Roth +--- + blockdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/blockdev.c b/blockdev.c +index bc7016a..097932c 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -460,7 +460,7 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts, + if (qemu_opt_get_bool(opts, "cache.direct", false)) { + bdrv_flags |= BDRV_O_NOCACHE; + } +- if (qemu_opt_get_bool(opts, "cache.no-flush", true)) { ++ if (qemu_opt_get_bool(opts, "cache.no-flush", false)) { + bdrv_flags |= BDRV_O_NO_FLUSH; + } + diff --git a/0038-virtio-blk-do-not-relay-a-previous-driver-s-WCE-conf.patch b/0038-virtio-blk-do-not-relay-a-previous-driver-s-WCE-conf.patch new file mode 100644 index 0000000..8e85b74 --- /dev/null +++ b/0038-virtio-blk-do-not-relay-a-previous-driver-s-WCE-conf.patch @@ -0,0 +1,111 @@ +From c8adc0db7e76e804692372a06ca02cc5a80b67d5 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2013 17:31:55 +0200 +Subject: [PATCH] virtio-blk: do not relay a previous driver's WCE + configuration to the current + +The following sequence happens: +- the SeaBIOS virtio-blk driver does not support the WCE feature, which +causes QEMU to disable writeback caching + +- the Linux virtio-blk driver resets the device, finds WCE is available +but writeback caching is disabled; tells block layer to not send cache +flush commands + +- the Linux virtio-blk driver sets the DRIVER_OK bit, which causes +writeback caching to be re-enabled, but the Linux virtio-blk driver does +not know of this side effect and cache flushes remain disabled + +The bug is at the third step. If the guest does know about CONFIG_WCE, +QEMU should ignore the WCE feature's state. The guest will control the +cache mode solely using configuration space. This change makes Linux +do flushes correctly, but Linux will keep SeaBIOS's writethrough mode. + +Hence, whenever the guest is reset, the cache mode of the disk should +be reset to whatever was specified in the "-drive" option. With this +change, the Linux virtio-blk driver finds that writeback caching is +enabled, and tells the block layer to send cache flush commands +appropriately. + +Reported-by: Rusty Russell +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit ef5bc96268ceec64769617dc53b0ac3a20ff351c) + +Signed-off-by: Michael Roth +--- + hw/block/virtio-blk.c | 24 ++++++++++++++++++++++-- + include/hw/virtio/virtio-blk.h | 1 + + 2 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index e2f55cc..49a23c3 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -460,9 +460,9 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running, + + static void virtio_blk_reset(VirtIODevice *vdev) + { +-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + VirtIOBlock *s = VIRTIO_BLK(vdev); + ++#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + if (s->dataplane) { + virtio_blk_data_plane_stop(s->dataplane); + } +@@ -473,6 +473,7 @@ static void virtio_blk_reset(VirtIODevice *vdev) + * are per-device request lists. + */ + bdrv_drain_all(); ++ bdrv_set_enable_write_cache(s->bs, s->original_wce); + } + + /* coalesce internal state, copy to pci i/o region 0 +@@ -564,7 +565,25 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) + } + + features = vdev->guest_features; +- bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE))); ++ ++ /* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send ++ * cache flushes. Thus, the "auto writethrough" behavior is never ++ * necessary for guests that support the VIRTIO_BLK_F_CONFIG_WCE feature. ++ * Leaving it enabled would break the following sequence: ++ * ++ * Guest started with "-drive cache=writethrough" ++ * Guest sets status to 0 ++ * Guest sets DRIVER bit in status field ++ * Guest reads host features (WCE=0, CONFIG_WCE=1) ++ * Guest writes guest features (WCE=0, CONFIG_WCE=1) ++ * Guest writes 1 to the WCE configuration field (writeback mode) ++ * Guest sets DRIVER_OK bit in status field ++ * ++ * s->bs would erroneously be placed in writethrough mode. ++ */ ++ if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) { ++ bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE))); ++ } + } + + static void virtio_blk_save(QEMUFile *f, void *opaque) +@@ -674,6 +693,7 @@ static int virtio_blk_device_init(VirtIODevice *vdev) + } + + blkconf_serial(&blk->conf, &blk->serial); ++ s->original_wce = bdrv_enable_write_cache(blk->conf.bs); + if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) { + return -1; + } +diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h +index b87cf49..41885da 100644 +--- a/include/hw/virtio/virtio-blk.h ++++ b/include/hw/virtio/virtio-blk.h +@@ -123,6 +123,7 @@ typedef struct VirtIOBlock { + BlockConf *conf; + VirtIOBlkConf blk; + unsigned short sector_mask; ++ bool original_wce; + VMChangeStateEntry *change; + #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + Notifier migration_state_notifier; diff --git a/0039-xhci-emulate-intr-endpoint-intervals-correctly.patch b/0039-xhci-emulate-intr-endpoint-intervals-correctly.patch new file mode 100644 index 0000000..9474f47 --- /dev/null +++ b/0039-xhci-emulate-intr-endpoint-intervals-correctly.patch @@ -0,0 +1,131 @@ +From dc6fbaa8322ca53f46d9a6cc7e2f82de5362ea83 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 28 Aug 2013 11:38:44 +0200 +Subject: [PATCH] xhci: emulate intr endpoint intervals correctly + +Respect the interval for interrupt endpoints, so we don't finish +transfers as fast as possible but at the rate configured by the guest. + +Fixes guest deadlocks triggered by interrupt storms. + +Cc: +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 4d7a81c06f5f17e019a2d3a18300500bd64f6f40) + +Signed-off-by: Michael Roth +--- + hw/usb/hcd-xhci.c | 44 +++++++++++++++++++++++++++++++++++++------- + 1 file changed, 37 insertions(+), 7 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index a6f55a1..8010a6d 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -355,6 +355,7 @@ typedef struct XHCITransfer { + unsigned int streamid; + bool in_xfer; + bool iso_xfer; ++ bool timed_xfer; + + unsigned int trb_count; + unsigned int trb_alloced; +@@ -1803,6 +1804,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) + + xfer->in_xfer = bmRequestType & USB_DIR_IN; + xfer->iso_xfer = false; ++ xfer->timed_xfer = false; + + if (xhci_setup_packet(xfer) < 0) { + return -1; +@@ -1818,6 +1820,17 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) + return 0; + } + ++static void xhci_calc_intr_kick(XHCIState *xhci, XHCITransfer *xfer, ++ XHCIEPContext *epctx, uint64_t mfindex) ++{ ++ uint64_t asap = ((mfindex + epctx->interval - 1) & ++ ~(epctx->interval-1)); ++ uint64_t kick = epctx->mfindex_last + epctx->interval; ++ ++ assert(epctx->interval != 0); ++ xfer->mfindex_kick = MAX(asap, kick); ++} ++ + static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer, + XHCIEPContext *epctx, uint64_t mfindex) + { +@@ -1840,8 +1853,8 @@ static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer, + } + } + +-static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer, +- XHCIEPContext *epctx, uint64_t mfindex) ++static void xhci_check_intr_iso_kick(XHCIState *xhci, XHCITransfer *xfer, ++ XHCIEPContext *epctx, uint64_t mfindex) + { + if (xfer->mfindex_kick > mfindex) { + qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock) + +@@ -1866,18 +1879,30 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx + switch(epctx->type) { + case ET_INTR_OUT: + case ET_INTR_IN: ++ xfer->pkts = 0; ++ xfer->iso_xfer = false; ++ xfer->timed_xfer = true; ++ mfindex = xhci_mfindex_get(xhci); ++ xhci_calc_intr_kick(xhci, xfer, epctx, mfindex); ++ xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex); ++ if (xfer->running_retry) { ++ return -1; ++ } ++ break; + case ET_BULK_OUT: + case ET_BULK_IN: + xfer->pkts = 0; + xfer->iso_xfer = false; ++ xfer->timed_xfer = false; + break; + case ET_ISO_OUT: + case ET_ISO_IN: + xfer->pkts = 1; + xfer->iso_xfer = true; ++ xfer->timed_xfer = true; + mfindex = xhci_mfindex_get(xhci); + xhci_calc_iso_kick(xhci, xfer, epctx, mfindex); +- xhci_check_iso_kick(xhci, xfer, epctx, mfindex); ++ xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex); + if (xfer->running_retry) { + return -1; + } +@@ -1938,13 +1963,18 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, + + trace_usb_xhci_xfer_retry(xfer); + assert(xfer->running_retry); +- if (xfer->iso_xfer) { +- /* retry delayed iso transfer */ ++ if (xfer->timed_xfer) { ++ /* time to kick the transfer? */ + mfindex = xhci_mfindex_get(xhci); +- xhci_check_iso_kick(xhci, xfer, epctx, mfindex); ++ xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex); + if (xfer->running_retry) { + return; + } ++ xfer->timed_xfer = 0; ++ xfer->running_retry = 1; ++ } ++ if (xfer->iso_xfer) { ++ /* retry iso transfer */ + if (xhci_setup_packet(xfer) < 0) { + return; + } +@@ -2030,7 +2060,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, + epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE; + ep = xfer->packet.ep; + } else { +- if (!xfer->iso_xfer) { ++ if (!xfer->timed_xfer) { + fprintf(stderr, "xhci: error firing data transfer\n"); + } + } diff --git a/0040-iov-avoid-orig_len-may-be-used-unitialized-warning.patch b/0040-iov-avoid-orig_len-may-be-used-unitialized-warning.patch new file mode 100644 index 0000000..c8f386c --- /dev/null +++ b/0040-iov-avoid-orig_len-may-be-used-unitialized-warning.patch @@ -0,0 +1,37 @@ +From b314120afdbab3d29885f47fc83bc55f43765968 Mon Sep 17 00:00:00 2001 +From: Michael Tokarev +Date: Sat, 14 Sep 2013 13:11:36 +0400 +Subject: [PATCH] iov: avoid "orig_len may be used unitialized" warning + +Signed-off-by: Wenchao Xia +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Michael Tokarev +(cherry picked from commit 2be178a475289286db80de5ddd7830e67e112bdd) + +Signed-off-by: Michael Roth +--- + util/iov.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/util/iov.c b/util/iov.c +index f705586..bb46c04 100644 +--- a/util/iov.c ++++ b/util/iov.c +@@ -181,13 +181,11 @@ ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, + assert(iov[niov].iov_len > tail); + orig_len = iov[niov].iov_len; + iov[niov++].iov_len = tail; +- } +- +- ret = do_send_recv(sockfd, iov, niov, do_send); +- +- /* Undo the changes above before checking for errors */ +- if (tail) { ++ ret = do_send_recv(sockfd, iov, niov, do_send); ++ /* Undo the changes above before checking for errors */ + iov[niov-1].iov_len = orig_len; ++ } else { ++ ret = do_send_recv(sockfd, iov, niov, do_send); + } + if (offset) { + iov[0].iov_base -= offset; diff --git a/0041-tap-Use-numbered-tap-tun-devices-on-all-BSD-OS-s.patch b/0041-tap-Use-numbered-tap-tun-devices-on-all-BSD-OS-s.patch new file mode 100644 index 0000000..67f0fe3 --- /dev/null +++ b/0041-tap-Use-numbered-tap-tun-devices-on-all-BSD-OS-s.patch @@ -0,0 +1,47 @@ +From 6bbb9d8100c90deb4843bfa3cf36e75b843c495b Mon Sep 17 00:00:00 2001 +From: Brad Smith +Date: Sat, 3 Aug 2013 22:20:41 -0400 +Subject: [PATCH] tap: Use numbered tap/tun devices on all *BSD OS's + +The following patch simplifies the *BSD tap/tun code and makes use of numbered +tap/tun interfaces on all *BSD OS's. NetBSD has a patch in their pkgsrc tree +to make use of this feature and DragonFly also supports this as well. + +Signed-off-by: Brad Smith +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit aa4f082f7526d39dac8e2ca64d192d858014ee10) + +Signed-off-by: Michael Roth +--- + net/tap-bsd.c | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/net/tap-bsd.c b/net/tap-bsd.c +index f61d580..90f8a02 100644 +--- a/net/tap-bsd.c ++++ b/net/tap-bsd.c +@@ -44,8 +44,6 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, + struct stat s; + #endif + +-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ +- defined(__OpenBSD__) || defined(__APPLE__) + /* if no ifname is given, always start the search from tap0/tun0. */ + int i; + char dname[100]; +@@ -76,15 +74,6 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, + dname, strerror(errno)); + return -1; + } +-#else +- TFR(fd = open("/dev/tap", O_RDWR)); +- if (fd < 0) { +- fprintf(stderr, +- "warning: could not open /dev/tap: no virtual network emulation: %s\n", +- strerror(errno)); +- return -1; +- } +-#endif + + #ifdef TAPGIFNAME + if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) { diff --git a/0042-rbd-avoid-qemu_rbd_snap_list-memory-leaks.patch b/0042-rbd-avoid-qemu_rbd_snap_list-memory-leaks.patch new file mode 100644 index 0000000..ebbe492 --- /dev/null +++ b/0042-rbd-avoid-qemu_rbd_snap_list-memory-leaks.patch @@ -0,0 +1,43 @@ +From fc06b430942e84a2a69e2a80a6d5b376a8064020 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 25 Sep 2013 16:00:48 +0200 +Subject: [PATCH] rbd: avoid qemu_rbd_snap_list() memory leaks + +When there are no snapshots qemu_rbd_snap_list() returns 0 and the +snapshot table pointer is NULL. Don't forget to free the snaps buffer +we allocated for librbd rbd_snap_list(). + +When the function succeeds don't forget to free the snaps buffer after +calling rbd_snap_list_end(). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit 9e6337d0818650362149b734d53edf9489f3acaa) + +Signed-off-by: Michael Roth +--- + block/rbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/block/rbd.c b/block/rbd.c +index cb71751..7e7c735 100644 +--- a/block/rbd.c ++++ b/block/rbd.c +@@ -934,7 +934,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs, + do { + snaps = g_malloc(sizeof(*snaps) * max_snaps); + snap_count = rbd_snap_list(s->image, snaps, &max_snaps); +- if (snap_count < 0) { ++ if (snap_count <= 0) { + g_free(snaps); + } + } while (snap_count == -ERANGE); +@@ -958,6 +958,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs, + sn_info->vm_clock_nsec = 0; + } + rbd_snap_list_end(snaps); ++ g_free(snaps); + + done: + *psn_tab = sn_tab; diff --git a/0043-vmdk-fix-cluster-size-check-for-flat-extents.patch b/0043-vmdk-fix-cluster-size-check-for-flat-extents.patch new file mode 100644 index 0000000..b8bac4c --- /dev/null +++ b/0043-vmdk-fix-cluster-size-check-for-flat-extents.patch @@ -0,0 +1,64 @@ +From 61fbeb6e81f648d25c2d3ba5f0d663d54abed1c1 Mon Sep 17 00:00:00 2001 +From: Fam Zheng +Date: Mon, 23 Sep 2013 17:18:29 +0800 +Subject: [PATCH] vmdk: fix cluster size check for flat extents + +We use the extent size as cluster size for flat extents (where no L1/L2 +table is allocated so it's safe) reuse sector calculating code with +sparse extents. + +Don't pass in the cluster size for adding flat extent, just set it to +sectors later, then the cluster size checking will not fail. + +The cluster_sectors is changed to int64_t to allow big flat extent. + +Without this, flat extent opening is broken: + + # qemu-img create -f vmdk -o subformat=monolithicFlat /tmp/a.vmdk 100G + Formatting '/tmp/a.vmdk', fmt=vmdk size=107374182400 compat6=off subformat='monolithicFlat' zeroed_grain=off + # qemu-img info /tmp/a.vmdk + image: /tmp/a.vmdk + file format: raw + virtual size: 0 (0 bytes) + disk size: 4.0K + +Signed-off-by: Fam Zheng +Signed-off-by: Kevin Wolf +(cherry picked from commit 301c7d38a0c359b91526391d13617386f3d9bb29) + +Signed-off-by: Michael Roth +--- + block/vmdk.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/block/vmdk.c b/block/vmdk.c +index 346bb5c..258a24f 100644 +--- a/block/vmdk.c ++++ b/block/vmdk.c +@@ -105,7 +105,7 @@ typedef struct VmdkExtent { + uint32_t l2_cache_offsets[L2_CACHE_SIZE]; + uint32_t l2_cache_counts[L2_CACHE_SIZE]; + +- unsigned int cluster_sectors; ++ int64_t cluster_sectors; + } VmdkExtent; + + typedef struct BDRVVmdkState { +@@ -416,7 +416,7 @@ static int vmdk_add_extent(BlockDriverState *bs, + extent->l1_size = l1_size; + extent->l1_entry_sectors = l2_size * cluster_sectors; + extent->l2_size = l2_size; +- extent->cluster_sectors = cluster_sectors; ++ extent->cluster_sectors = flat ? sectors : cluster_sectors; + + if (s->num_extents > 1) { + extent->end_sector = (*(extent - 1)).end_sector + extent->sectors; +@@ -736,7 +736,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, + VmdkExtent *extent; + + ret = vmdk_add_extent(bs, extent_file, true, sectors, +- 0, 0, 0, 0, sectors, &extent); ++ 0, 0, 0, 0, 0, &extent); + if (ret < 0) { + return ret; + } diff --git a/0044-piix4-disable-io-on-reset.patch b/0044-piix4-disable-io-on-reset.patch new file mode 100644 index 0000000..e37b62b --- /dev/null +++ b/0044-piix4-disable-io-on-reset.patch @@ -0,0 +1,33 @@ +From ae00a27feab0ca12d2a802cfae9ee65ba3d43602 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Wed, 11 Sep 2013 13:33:31 +0300 +Subject: [PATCH] piix4: disable io on reset + +io base register at 0x40 is cleared on reset, +but io is not disabled until some other event +happens to call pm_io_space_update. + +Invoke pm_io_space_update directly to make this +consistent. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit c046e8c4a26c902ca1b4f5bdf668a2da6bc75f54) + +Signed-off-by: Michael Roth +--- + hw/acpi/piix4.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c +index c885690..3aaf18c 100644 +--- a/hw/acpi/piix4.c ++++ b/hw/acpi/piix4.c +@@ -380,6 +380,7 @@ static void piix4_reset(void *opaque) + /* Mark SMM as already inited (until KVM supports SMM). */ + pci_conf[0x5B] = 0x02; + } ++ pm_io_space_update(s); + piix4_update_hotplug(s); + } + diff --git a/0045-coroutine-add-.-configure-disable-coroutine-pool.patch b/0045-coroutine-add-.-configure-disable-coroutine-pool.patch new file mode 100644 index 0000000..2c416fd --- /dev/null +++ b/0045-coroutine-add-.-configure-disable-coroutine-pool.patch @@ -0,0 +1,163 @@ +From ba20326a937421c50a775907dc9ac726bb9a9b50 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 11 Sep 2013 16:42:35 +0200 +Subject: [PATCH] coroutine: add ./configure --disable-coroutine-pool + +The 'gthread' coroutine backend was written before the freelist (aka +pool) existed in qemu-coroutine.c. + +This means that every thread is expected to exit when its coroutine +terminates. It is not possible to reuse threads from a pool. + +This patch automatically disables the pool when 'gthread' is used. This +allows the 'gthread' backend to work again (for example, +tests/test-coroutine completes successfully instead of hanging). + +I considered implementing thread reuse but I don't want quirks like CPU +affinity differences due to coroutine threads being recycled. The +'gthread' backend is a reference backend and it's therefore okay to skip +the pool optimization. + +Note this patch also makes it easy to toggle the pool for benchmarking +purposes: + + ./configure --with-coroutine-backend=ucontext \ + --disable-coroutine-pool + +Reported-by: Gabriel Kerneis +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Gabriel Kerneis +Signed-off-by: Kevin Wolf +(cherry picked from commit 70c60c089fdc6bf8a79324e492c13e8c08d55942) + +Signed-off-by: Michael Roth +--- + configure | 24 ++++++++++++++++++++++++ + qemu-coroutine.c | 34 +++++++++++++++++++--------------- + 2 files changed, 43 insertions(+), 15 deletions(-) + +diff --git a/configure b/configure +index 18fa608..4cf672d 100755 +--- a/configure ++++ b/configure +@@ -235,6 +235,7 @@ guest_agent="" + want_tools="yes" + libiscsi="" + coroutine="" ++coroutine_pool="" + seccomp="" + glusterfs="" + glusterfs_discard="no" +@@ -871,6 +872,10 @@ for opt do + ;; + --with-coroutine=*) coroutine="$optarg" + ;; ++ --disable-coroutine-pool) coroutine_pool="no" ++ ;; ++ --enable-coroutine-pool) coroutine_pool="yes" ++ ;; + --disable-docs) docs="no" + ;; + --enable-docs) docs="yes" +@@ -1152,6 +1157,8 @@ echo " --disable-seccomp disable seccomp support" + echo " --enable-seccomp enables seccomp support" + echo " --with-coroutine=BACKEND coroutine backend. Supported options:" + echo " gthread, ucontext, sigaltstack, windows" ++echo " --disable-coroutine-pool disable coroutine freelist (worse performance)" ++echo " --enable-coroutine-pool enable coroutine freelist (better performance)" + echo " --enable-glusterfs enable GlusterFS backend" + echo " --disable-glusterfs disable GlusterFS backend" + echo " --enable-gcov enable test coverage analysis with gcov" +@@ -3240,6 +3247,17 @@ else + esac + fi + ++if test "$coroutine_pool" = ""; then ++ if test "$coroutine" = "gthread"; then ++ coroutine_pool=no ++ else ++ coroutine_pool=yes ++ fi ++fi ++if test "$coroutine" = "gthread" -a "$coroutine_pool" = "yes"; then ++ error_exit "'gthread' coroutine backend does not support pool (use --disable-coroutine-pool)" ++fi ++ + ########################################## + # check if we have open_by_handle_at + +@@ -3605,6 +3623,7 @@ echo "libiscsi support $libiscsi" + echo "build guest agent $guest_agent" + echo "seccomp support $seccomp" + echo "coroutine backend $coroutine" ++echo "coroutine pool $coroutine_pool" + echo "GlusterFS support $glusterfs" + echo "virtio-blk-data-plane $virtio_blk_data_plane" + echo "gcov $gcov_tool" +@@ -3954,6 +3973,11 @@ if test "$rbd" = "yes" ; then + fi + + echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak ++if test "$coroutine_pool" = "yes" ; then ++ echo "CONFIG_COROUTINE_POOL=1" >> $config_host_mak ++else ++ echo "CONFIG_COROUTINE_POOL=0" >> $config_host_mak ++fi + + if test "$open_by_handle_at" = "yes" ; then + echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak +diff --git a/qemu-coroutine.c b/qemu-coroutine.c +index 423430d..4708521 100644 +--- a/qemu-coroutine.c ++++ b/qemu-coroutine.c +@@ -30,15 +30,17 @@ static unsigned int pool_size; + + Coroutine *qemu_coroutine_create(CoroutineEntry *entry) + { +- Coroutine *co; +- +- qemu_mutex_lock(&pool_lock); +- co = QSLIST_FIRST(&pool); +- if (co) { +- QSLIST_REMOVE_HEAD(&pool, pool_next); +- pool_size--; ++ Coroutine *co = NULL; ++ ++ if (CONFIG_COROUTINE_POOL) { ++ qemu_mutex_lock(&pool_lock); ++ co = QSLIST_FIRST(&pool); ++ if (co) { ++ QSLIST_REMOVE_HEAD(&pool, pool_next); ++ pool_size--; ++ } ++ qemu_mutex_unlock(&pool_lock); + } +- qemu_mutex_unlock(&pool_lock); + + if (!co) { + co = qemu_coroutine_new(); +@@ -51,15 +53,17 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry) + + static void coroutine_delete(Coroutine *co) + { +- qemu_mutex_lock(&pool_lock); +- if (pool_size < POOL_MAX_SIZE) { +- QSLIST_INSERT_HEAD(&pool, co, pool_next); +- co->caller = NULL; +- pool_size++; ++ if (CONFIG_COROUTINE_POOL) { ++ qemu_mutex_lock(&pool_lock); ++ if (pool_size < POOL_MAX_SIZE) { ++ QSLIST_INSERT_HEAD(&pool, co, pool_next); ++ co->caller = NULL; ++ pool_size++; ++ qemu_mutex_unlock(&pool_lock); ++ return; ++ } + qemu_mutex_unlock(&pool_lock); +- return; + } +- qemu_mutex_unlock(&pool_lock); + + qemu_coroutine_delete(co); + } diff --git a/0046-qemu-Adjust-qemu-wakeup.patch b/0046-qemu-Adjust-qemu-wakeup.patch new file mode 100644 index 0000000..973119b --- /dev/null +++ b/0046-qemu-Adjust-qemu-wakeup.patch @@ -0,0 +1,123 @@ +From bc05a488b49f903e404323b76ca9b675318393fc Mon Sep 17 00:00:00 2001 +From: "Liu, Jinsong" +Date: Wed, 25 Sep 2013 16:38:29 +0000 +Subject: [PATCH] qemu: Adjust qemu wakeup + +Currently Xen hvm s3 has a bug coming from the difference between +qemu-traditioanl and qemu-xen. For qemu-traditional, the way to +resume from hvm s3 is via 'xl trigger' command. However, for +qemu-xen, the way to resume from hvm s3 inherited from standard +qemu, i.e. via QMP, and it doesn't work under Xen. + +The root cause is, for qemu-xen, 'xl trigger' command didn't reset +devices, while QMP didn't unpause hvm domain though they did qemu +system reset. + +We have two qemu patches and one xl patch to fix Xen hvm s3 bug. +This patch is the qemu patch 1. It adjusts qemu wakeup so that +Xen s3 resume logic (which will be implemented at qemu patch 2) +will be notified after qemu system reset. + +Signed-off-by: Liu Jinsong +Signed-off-by: Stefano Stabellini +Reviewed-by: Paolo Bonzini +Reviewed-by: Anthony PERARD +(cherry picked from commit 4bc78a877252d772b983810a7d2c0be00e9be70e) + +Signed-off-by: Michael Roth +--- + hw/acpi/core.c | 3 ++- + include/sysemu/sysemu.h | 4 +++- + vl.c | 15 +++++++-------- + 3 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/hw/acpi/core.c b/hw/acpi/core.c +index b07feda..769cfdb 100644 +--- a/hw/acpi/core.c ++++ b/hw/acpi/core.c +@@ -324,12 +324,13 @@ static void acpi_notify_wakeup(Notifier *notifier, void *data) + (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); + break; + case QEMU_WAKEUP_REASON_OTHER: +- default: + /* ACPI_BITMASK_WAKE_STATUS should be set on resume. + Pretend that resume was caused by power button */ + ar->pm1.evt.sts |= + (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); + break; ++ default: ++ break; + } + } + +diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h +index d7a77b6..1a77c99 100644 +--- a/include/sysemu/sysemu.h ++++ b/include/sysemu/sysemu.h +@@ -39,9 +39,11 @@ int vm_stop(RunState state); + int vm_stop_force_state(RunState state); + + typedef enum WakeupReason { +- QEMU_WAKEUP_REASON_OTHER = 0, ++ /* Always keep QEMU_WAKEUP_REASON_NONE = 0 */ ++ QEMU_WAKEUP_REASON_NONE = 0, + QEMU_WAKEUP_REASON_RTC, + QEMU_WAKEUP_REASON_PMTIMER, ++ QEMU_WAKEUP_REASON_OTHER, + } WakeupReason; + + void qemu_system_reset_request(void); +diff --git a/vl.c b/vl.c +index f422a1c..2160933 100644 +--- a/vl.c ++++ b/vl.c +@@ -1792,14 +1792,14 @@ static pid_t shutdown_pid; + static int powerdown_requested; + static int debug_requested; + static int suspend_requested; +-static int wakeup_requested; ++static WakeupReason wakeup_reason; + static NotifierList powerdown_notifiers = + NOTIFIER_LIST_INITIALIZER(powerdown_notifiers); + static NotifierList suspend_notifiers = + NOTIFIER_LIST_INITIALIZER(suspend_notifiers); + static NotifierList wakeup_notifiers = + NOTIFIER_LIST_INITIALIZER(wakeup_notifiers); +-static uint32_t wakeup_reason_mask = ~0; ++static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE); + static RunState vmstop_requested = RUN_STATE_MAX; + + int qemu_shutdown_requested_get(void) +@@ -1849,11 +1849,9 @@ static int qemu_suspend_requested(void) + return r; + } + +-static int qemu_wakeup_requested(void) ++static WakeupReason qemu_wakeup_requested(void) + { +- int r = wakeup_requested; +- wakeup_requested = 0; +- return r; ++ return wakeup_reason; + } + + static int qemu_powerdown_requested(void) +@@ -1970,8 +1968,7 @@ void qemu_system_wakeup_request(WakeupReason reason) + return; + } + runstate_set(RUN_STATE_RUNNING); +- notifier_list_notify(&wakeup_notifiers, &reason); +- wakeup_requested = 1; ++ wakeup_reason = reason; + qemu_notify_event(); + } + +@@ -2063,6 +2060,8 @@ static bool main_loop_should_exit(void) + pause_all_vcpus(); + cpu_synchronize_all_states(); + qemu_system_reset(VMRESET_SILENT); ++ notifier_list_notify(&wakeup_notifiers, &wakeup_reason); ++ wakeup_reason = QEMU_WAKEUP_REASON_NONE; + resume_all_vcpus(); + monitor_protocol_event(QEVENT_WAKEUP, NULL); + } diff --git a/0047-qemu-Add-qemu-xen-logic-for-Xen-HVM-S3-resume.patch b/0047-qemu-Add-qemu-xen-logic-for-Xen-HVM-S3-resume.patch new file mode 100644 index 0000000..f6e06a5 --- /dev/null +++ b/0047-qemu-Add-qemu-xen-logic-for-Xen-HVM-S3-resume.patch @@ -0,0 +1,53 @@ +From 1b5f7709411a412ec8ce21004a47f51ab6c3f3ad Mon Sep 17 00:00:00 2001 +From: "Liu, Jinsong" +Date: Wed, 25 Sep 2013 16:40:23 +0000 +Subject: [PATCH] qemu: Add qemu xen logic for Xen HVM S3 resume + +This patch is qemu patch 2 to fix Xen HVM S3 bug, adding qemu +xen logic. When qemu wakeup, qemu xen logic is notified and +hypercall to xen hypervisor to unpause domain. + +Signed-off-by: Liu Jinsong +Signed-off-by: Stefano Stabellini +Reviewed-by: Anthony PERARD +(cherry picked from commit 11addd0ab9371af2b6ec028c7fe4e4c4992252fc) + +Signed-off-by: Michael Roth +--- + xen-all.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/xen-all.c b/xen-all.c +index e1d0694..7894ac6 100644 +--- a/xen-all.c ++++ b/xen-all.c +@@ -98,6 +98,7 @@ typedef struct XenIOState { + + Notifier exit; + Notifier suspend; ++ Notifier wakeup; + } XenIOState; + + /* Xen specific function for piix pci */ +@@ -1060,6 +1061,11 @@ static void xen_read_physmap(XenIOState *state) + free(entries); + } + ++static void xen_wakeup_notifier(Notifier *notifier, void *data) ++{ ++ xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 0); ++} ++ + int xen_hvm_init(MemoryRegion **ram_memory) + { + int i, rc; +@@ -1089,6 +1095,9 @@ int xen_hvm_init(MemoryRegion **ram_memory) + state->suspend.notify = xen_suspend_notifier; + qemu_register_suspend_notifier(&state->suspend); + ++ state->wakeup.notify = xen_wakeup_notifier; ++ qemu_register_wakeup_notifier(&state->wakeup); ++ + xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn); + DPRINTF("shared page at pfn %lx\n", ioreq_pfn); + state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE, diff --git a/0048-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch b/0048-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch new file mode 100644 index 0000000..d921981 --- /dev/null +++ b/0048-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch @@ -0,0 +1,154 @@ +From fdcbe7d587a64dec0db0d3c9a3b230c39efbfeef 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 +--- + hw/scsi/scsi-bus.c | 44 +++++++++++++++++++++++++++++++++----------- + include/hw/scsi/scsi.h | 2 ++ + 2 files changed, 35 insertions(+), 11 deletions(-) + +diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c +index 8fe4f4c..ad26c25 100644 +--- a/hw/scsi/scsi-bus.c ++++ b/hw/scsi/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), +@@ -317,7 +319,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) +@@ -361,14 +364,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; +@@ -387,6 +388,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; +@@ -411,7 +415,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; + } +@@ -455,8 +459,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); +@@ -501,11 +505,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, + }; + + +@@ -1365,7 +1387,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/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h +index 8786531..18cb694 100644 +--- a/include/hw/scsi/scsi.h ++++ b/include/hw/scsi/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/0049-Update-VERSION-for-1.6.1-release.patch b/0049-Update-VERSION-for-1.6.1-release.patch new file mode 100644 index 0000000..30bfee2 --- /dev/null +++ b/0049-Update-VERSION-for-1.6.1-release.patch @@ -0,0 +1,17 @@ +From 62ecc3a0e3c77a4944c92a02dd7fae2ab1f2290d Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Fri, 4 Oct 2013 10:21:43 -0500 +Subject: [PATCH] Update VERSION for 1.6.1 release + +Signed-off-by: Michael Roth +--- + VERSION | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/VERSION b/VERSION +index dc1e644..9c6d629 100644 +--- a/VERSION ++++ b/VERSION +@@ -1 +1 @@ +-1.6.0 ++1.6.1 diff --git a/0101-Fix-migration-from-qemu-kvm.patch b/0101-Fix-migration-from-qemu-kvm.patch new file mode 100644 index 0000000..a263329 --- /dev/null +++ b/0101-Fix-migration-from-qemu-kvm.patch @@ -0,0 +1,212 @@ +From 2196426a9b081cb99f4bdefb854aaa206bdd0392 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Fri, 16 Aug 2013 12:14:51 -0400 +Subject: [PATCH] Fix migration from qemu-kvm + +Details are in the code comments for each change. Just lumped this together +to ease patch maintenance. + +Everything except the video memory bits can likely be dropped by Fedora 21 +time frame. Need to figure out if there's anything to upstream for the +video memory bits. +--- + hw/acpi/piix4.c | 8 ++++++- + hw/display/qxl.c | 9 ++++---- + hw/i386/pc_piix.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---- + hw/timer/i8254_common.c | 7 +++++- + 4 files changed, 74 insertions(+), 11 deletions(-) + +diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c +index 3aaf18c..6fbe57c 100644 +--- a/hw/acpi/piix4.c ++++ b/hw/acpi/piix4.c +@@ -289,7 +289,13 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) + static const VMStateDescription vmstate_acpi = { + .name = "piix4_pm", + .version_id = 3, +- .minimum_version_id = 3, ++ /* ++ * 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 = 3, ++ .minimum_version_id = 2, + .minimum_version_id_old = 1, + .load_state_old = acpi_load_old, + .post_load = vmstate_acpi_post_load, +diff --git a/hw/display/qxl.c b/hw/display/qxl.c +index c537057..7ef3eff 100644 +--- a/hw/display/qxl.c ++++ b/hw/display/qxl.c +@@ -307,16 +307,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) +@@ -1981,7 +1979,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, OBJECT(qxl), "qxl.vrom", + qxl->rom_size); + vmstate_register_ram(&qxl->rom_bar, &qxl->pci.qdev); +@@ -2309,6 +2307,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/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index 3df2ff9..28216ee 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -377,6 +377,24 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { + DEFAULT_MACHINE_OPTIONS, + }; + ++/* ++ * 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. ++ */ ++ + #define PC_COMPAT_1_3 \ + PC_COMPAT_1_4, \ + {\ +@@ -395,8 +413,17 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { + .driver = "e1000",\ + .property = "autonegotiation",\ + .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 = { + .name = "pc-1.3", + .desc = "Standard PC", +@@ -409,6 +436,19 @@ static QEMUMachine pc_machine_v1_3 = { + DEFAULT_MACHINE_OPTIONS, + }; + ++ ++/* ++ * 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. ++ * ++ * 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. ++ */ ++ + #define PC_COMPAT_1_2 \ + PC_COMPAT_1_3,\ + {\ +@@ -432,6 +472,10 @@ static QEMUMachine pc_machine_v1_3 = { + .property = "revision",\ + .value = stringify(3),\ + },{\ ++ .driver = "cirrus-vga",\ ++ .property = "vgamem_mb",\ ++ .value = stringify(16),\ ++ },{\ + .driver = "VGA",\ + .property = "mmio",\ + .value = "off",\ +@@ -462,25 +506,34 @@ static QEMUMachine pc_machine_v1_2 = { + },{\ + .driver = "VGA",\ + .property = "vgamem_mb",\ +- .value = stringify(8),\ ++ .value = stringify(16),\ + },{\ + .driver = "vmware-svga",\ + .property = "vgamem_mb",\ +- .value = stringify(8),\ ++ .value = stringify(16),\ + },{\ + .driver = "qxl-vga",\ + .property = "vgamem_mb",\ +- .value = stringify(8),\ ++ .value = stringify(16),\ + },{\ + .driver = "qxl",\ + .property = "vgamem_mb",\ +- .value = stringify(8),\ ++ .value = stringify(16),\ + },{\ + .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 = { + .name = "pc-1.1", + .desc = "Standard PC", +diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c +index 4e5bf0b..cbc00a0 100644 +--- a/hw/timer/i8254_common.c ++++ b/hw/timer/i8254_common.c +@@ -267,7 +267,12 @@ static const VMStateDescription vmstate_pit_common = { + .pre_save = pit_dispatch_pre_save, + .post_load = pit_dispatch_post_load, + .fields = (VMStateField[]) { +- VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), ++ /* 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_V(channels[0].irq_disabled, PITCommonState, 3), ++ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), + VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, + vmstate_pit_channel, PITChannelState), + VMSTATE_INT64(channels[0].next_transition_time, diff --git a/0102-isapc-disable-kvmvapic.patch b/0102-isapc-disable-kvmvapic.patch new file mode 100644 index 0000000..4adf992 --- /dev/null +++ b/0102-isapc-disable-kvmvapic.patch @@ -0,0 +1,36 @@ +From 85a924af30f31a4f701ee6f18d84dd27aa02f47b 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) + +Signed-off-by: Cole Robinson +--- + hw/i386/pc_piix.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index 28216ee..2f2cb4d 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -795,7 +795,11 @@ static QEMUMachine isapc_machine = { + .init = pc_init_isa, + .max_cpus = 1, + .compat_props = (GlobalProperty[]) { +- { /* end of list */ } ++ { ++ .driver = "apic-common", ++ .property = "vapic", ++ .value = "off", ++ }, + }, + DEFAULT_MACHINE_OPTIONS, + }; diff --git a/0103-pci-do-not-export-pci_bus_reset.patch b/0103-pci-do-not-export-pci_bus_reset.patch new file mode 100644 index 0000000..21c6cef --- /dev/null +++ b/0103-pci-do-not-export-pci_bus_reset.patch @@ -0,0 +1,72 @@ +From 07873f45017c04994496d8dc3f7acb60358bba49 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 + +qbus_reset_all can be used instead. There is no semantic change +because pcibus_reset returns 1 and takes care of the device +tree traversal. + +This will be necessary once the traversal is done always in +qbus_reset_all *before* invoking pcibus_reset itself. + +Tested-by: Claudio Bley +Signed-off-by: Paolo Bonzini +--- + 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 4c004f5..0389375 100644 +--- a/hw/pci/pci.c ++++ b/hw/pci/pci.c +@@ -210,8 +210,9 @@ void pci_device_reset(PCIDevice *dev) + * Trigger pci bus reset under a given bus. + * To be called on RST# assert. + */ +-void pci_bus_reset(PCIBus *bus) ++static int pcibus_reset(BusState *qbus) + { ++ PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus); + int i; + + for (i = 0; i < bus->nirq; i++) { +@@ -222,11 +223,6 @@ void pci_bus_reset(PCIBus *bus) + pci_device_reset(bus->devices[i]); + } + } +-} +- +-static int pcibus_reset(BusState *qbus) +-{ +- pci_bus_reset(DO_UPCAST(PCIBus, qbus, qbus)); + + /* topology traverse is done by pci_bus_reset(). + Tell qbus/qdev walker not to traverse the tree */ +diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c +index a90671d..5d0e5ff 100644 +--- a/hw/pci/pci_bridge.c ++++ b/hw/pci/pci_bridge.c +@@ -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. */ +- pci_bus_reset(&s->sec_bus); ++ qbus_reset_all(&s->sec_bus.qbus); + } + } + +diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h +index ccec2ba..32f1419 100644 +--- a/include/hw/pci/pci.h ++++ b/include/hw/pci/pci.h +@@ -376,7 +376,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/0104-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch b/0104-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch new file mode 100644 index 0000000..8580f62 --- /dev/null +++ b/0104-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch @@ -0,0 +1,141 @@ +From cf09bc533d82f2b16d1e9f4888c1afd977ca256d 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 + functions + +Resetting should be done in post-order, not pre-order. However, +qdev_walk_children and qbus_walk_children do not allow this. Fix +it by adding two extra arguments to the functions. + +Tested-by: Claudio Bley +Signed-off-by: Paolo Bonzini +--- + hw/core/qdev.c | 45 +++++++++++++++++++++++++++++++++------------ + include/hw/qdev-core.h | 13 +++++++++---- + 2 files changed, 42 insertions(+), 16 deletions(-) + +diff --git a/hw/core/qdev.c b/hw/core/qdev.c +index 9190a7e..842804f 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) + { +- qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL); ++ qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); + } + + void qbus_reset_all(BusState *bus) + { +- qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL); ++ qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); + } + + void qbus_reset_all_fn(void *opaque) +@@ -343,49 +343,70 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) + return NULL; + } + +-int qbus_walk_children(BusState *bus, 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) + { + BusChild *kid; + int err; + +- if (busfn) { +- err = busfn(bus, opaque); ++ if (pre_busfn) { ++ err = pre_busfn(bus, opaque); + if (err) { + return err; + } + } + + QTAILQ_FOREACH(kid, &bus->children, sibling) { +- err = qdev_walk_children(kid->child, devfn, busfn, opaque); ++ err = qdev_walk_children(kid->child, ++ pre_devfn, pre_busfn, ++ post_devfn, post_busfn, opaque); + if (err < 0) { + return err; + } + } + ++ if (post_busfn) { ++ err = post_busfn(bus, opaque); ++ if (err) { ++ return err; ++ } ++ } ++ + return 0; + } + +-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, +- qbus_walkerfn *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) + { + BusState *bus; + int err; + +- if (devfn) { +- err = devfn(dev, opaque); ++ if (pre_devfn) { ++ err = pre_devfn(dev, opaque); + if (err) { + return err; + } + } + + QLIST_FOREACH(bus, &dev->child_bus, sibling) { +- err = qbus_walk_children(bus, devfn, busfn, opaque); ++ err = qbus_walk_children(bus, pre_devfn, pre_busfn, ++ post_devfn, post_busfn, opaque); + if (err < 0) { + return err; + } + } + ++ if (post_devfn) { ++ err = post_devfn(dev, opaque); ++ if (err) { ++ return err; ++ } ++ } ++ + return 0; + } + +diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h +index 46972f4..c6c9b14 100644 +--- a/include/hw/qdev-core.h ++++ b/include/hw/qdev-core.h +@@ -270,10 +270,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/0105-qdev-switch-reset-to-post-order.patch b/0105-qdev-switch-reset-to-post-order.patch new file mode 100644 index 0000000..2f533e5 --- /dev/null +++ b/0105-qdev-switch-reset-to-post-order.patch @@ -0,0 +1,143 @@ +From 41a2077cea8ce006dbef885bcb0778af05a0b159 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 + +Post-order is the only sensible direction for the reset signals. +For example, suppose pre-order is used and the parent has some data +structures that cache children state (for example a list of active +requests). When the reset method is invoked on the parent, these caches +could be in any state. + +If post-order is used, on the other hand, these will be in a known state +when the reset method is invoked on the parent. + +This change means that it is no longer possible to block the visit of +the devices, so the callback is changed to return void. This is not +a problem, because PCI was returning 1 exactly in order to achieve the +same ordering that this patch implements. + +PCI can then rely on the qdev core having sent a "reset signal" +(whatever that means) to the device, and only do the PCI-specific +initialization with the new function pci_do_device_reset, extracted +from pci_device_reset. There is no change in the operation of FLR, +which used and still uses pci_device_reset. + +Tested-by: Claudio Bley +Signed-off-by: Paolo Bonzini +--- + 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 842804f..87d7e1e 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 0389375..bbca696 100644 +--- a/hw/pci/pci.c ++++ b/hw/pci/pci.c +@@ -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 Property pci_props[] = { + DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), +@@ -165,16 +165,10 @@ void pci_device_deassert_intx(PCIDevice *dev) + } + } + +-/* +- * This function is called on #RST and FLR. +- * FLR if PCI_EXP_DEVCTL_BCR_FLR is set +- */ +-void pci_device_reset(PCIDevice *dev) ++static void pci_do_device_reset(PCIDevice *dev) + { + int r; + +- qdev_reset_all(&dev->qdev); +- + dev->irq_state = 0; + pci_update_irq_status(dev); + pci_device_deassert_intx(dev); +@@ -207,10 +201,21 @@ void pci_device_reset(PCIDevice *dev) + } + + /* ++ * This function is called on #RST and FLR. ++ * FLR if PCI_EXP_DEVCTL_BCR_FLR is set ++ */ ++void pci_device_reset(PCIDevice *dev) ++{ ++ qdev_reset_all(&dev->qdev); ++ pci_do_device_reset(dev); ++} ++ ++/* + * Trigger pci bus reset under a given bus. +- * To be called on RST# assert. ++ * Called via qbus_reset_all on RST# assert, after the devices ++ * have been reset qdev_reset_all-ed already. + */ +-static int pcibus_reset(BusState *qbus) ++static void pcibus_reset(BusState *qbus) + { + PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus); + int i; +@@ -220,13 +225,9 @@ static int pcibus_reset(BusState *qbus) + } + for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { + if (bus->devices[i]) { +- pci_device_reset(bus->devices[i]); ++ pci_do_device_reset(bus->devices[i]); + } + } +- +- /* topology traverse is done by pci_bus_reset(). +- Tell qbus/qdev walker not to traverse the tree */ +- return 1; + } + + 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 c6c9b14..89dcbad 100644 +--- a/include/hw/qdev-core.h ++++ b/include/hw/qdev-core.h +@@ -174,7 +174,7 @@ struct BusClass { + * bindings can be found at http://playground.sun.com/1275/bindings/. + */ + char *(*get_fw_dev_path)(DeviceState *dev); +- int (*reset)(BusState *bus); ++ void (*reset)(BusState *bus); + /* maximum devices allowed on the bus, 0: no limit. */ + int max_dev; + }; diff --git a/0106-virtio-bus-remove-vdev-field.patch b/0106-virtio-bus-remove-vdev-field.patch new file mode 100644 index 0000000..617326f --- /dev/null +++ b/0106-virtio-bus-remove-vdev-field.patch @@ -0,0 +1,251 @@ +From ed35f9edcc420b4f8c1f909bc7cfb002a54f437b 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 | 67 ++++++++++++++++++++++++------------------ + hw/virtio/virtio-mmio.c | 9 +++--- + hw/virtio/virtio-pci.c | 2 +- + include/hw/virtio/virtio-bus.h | 16 +++++++--- + 4 files changed, 57 insertions(+), 37 deletions(-) + +diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c +index 6849a01..669ce38 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,75 +56,84 @@ 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); + } + } + + /* Destroy the VirtIODevice */ + void virtio_bus_destroy_device(VirtioBusState *bus) + { +- DeviceState *qdev; + 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); + } +- qdev = DEVICE(bus->vdev); +- qdev_free(qdev); +- bus->vdev = NULL; ++ qdev_free(DEVICE(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; + } +@@ -135,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 4bd2953..8f7b764 100644 +--- a/hw/virtio/virtio-mmio.c ++++ b/hw/virtio/virtio-mmio.c +@@ -94,7 +94,7 @@ static void virtio_mmio_bus_new(VirtioBusState *bus, VirtIOMMIOProxy *dev); + 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); + +@@ -184,7 +184,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); +@@ -297,12 +297,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 41b96ce..55617a6 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -942,7 +942,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/0107-virtio-pci-remove-vdev-field.patch b/0107-virtio-pci-remove-vdev-field.patch new file mode 100644 index 0000000..f8000e7 --- /dev/null +++ b/0107-virtio-pci-remove-vdev-field.patch @@ -0,0 +1,447 @@ +From 1d388b4fda2c4c9d00dc6ae91aaf35eb9fc04c26 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 55617a6..6fd6d6d 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -112,31 +112,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 +- qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); ++ qemu_set_irq(proxy->pci_dev.irq[0], 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) { +@@ -145,12 +153,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; + } +@@ -158,13 +166,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); + } +@@ -174,7 +184,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; + +@@ -199,6 +210,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) || +@@ -208,7 +220,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; + } + +@@ -222,7 +234,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; + } + +@@ -235,6 +247,7 @@ assign_error: + + static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) + { ++ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int r; + int n; + +@@ -243,7 +256,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; + } + +@@ -256,7 +269,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) { +@@ -271,7 +284,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 +@@ -298,7 +311,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); + } + +@@ -334,7 +347,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) { +@@ -380,6 +393,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) { +@@ -389,16 +403,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); + } +@@ -412,6 +426,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; +@@ -423,19 +438,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; + } + } +@@ -454,6 +469,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); + +@@ -461,8 +477,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); + } + } + +@@ -505,7 +520,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, irqfd->virq); +@@ -516,7 +532,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; +@@ -528,7 +545,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; +@@ -577,7 +594,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); +@@ -605,8 +622,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; +@@ -625,10 +643,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 { +@@ -641,13 +659,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); + } +@@ -657,7 +676,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++) { +@@ -687,7 +706,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++) { +@@ -706,7 +725,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; +@@ -738,8 +757,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) { +@@ -754,7 +774,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; +@@ -769,7 +789,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) && +@@ -863,11 +883,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; + } +@@ -942,8 +963,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/0108-virtio-ccw-remove-vdev-field.patch b/0108-virtio-ccw-remove-vdev-field.patch new file mode 100644 index 0000000..d0c8d62 --- /dev/null +++ b/0108-virtio-ccw-remove-vdev-field.patch @@ -0,0 +1,293 @@ +From a9b1f1aeba8167ae90aecea9b8ca223faf33ae90 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 8835bd4..0fc7387 100644 +--- a/hw/s390x/virtio-ccw.c ++++ b/hw/s390x/virtio-ccw.c +@@ -56,9 +56,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; + } +@@ -66,7 +67,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; +@@ -96,6 +98,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) || +@@ -103,8 +106,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); +@@ -117,7 +121,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); +@@ -131,13 +135,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); +@@ -188,7 +194,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; +@@ -199,23 +205,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; + } + +@@ -229,6 +235,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; +@@ -271,7 +278,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: +@@ -318,7 +325,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 +@@ -336,30 +343,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; +@@ -370,9 +377,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; + } +@@ -396,9 +403,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); +@@ -462,7 +469,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); +@@ -494,7 +501,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. */ +@@ -607,7 +613,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, +@@ -891,9 +897,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; +@@ -933,9 +940,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); +@@ -951,16 +959,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); +@@ -972,7 +980,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/0109-virtio-bus-cleanup-plug-unplug-interface.patch b/0109-virtio-bus-cleanup-plug-unplug-interface.patch new file mode 100644 index 0000000..b8a91f4 --- /dev/null +++ b/0109-virtio-bus-cleanup-plug-unplug-interface.patch @@ -0,0 +1,148 @@ +From fe02fcc2b929e6a678ec783cb80890b79b7dca78 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 669ce38..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); + } +- qdev_free(DEVICE(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/0110-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch b/0110-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch new file mode 100644 index 0000000..57c2353 --- /dev/null +++ b/0110-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch @@ -0,0 +1,53 @@ +From aa75555e6fb5cae0e495cb5f7d9f3511ad5ac6ce 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 49a23c3..aa37cc9 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -729,20 +729,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[] = { +@@ -754,10 +752,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/0111-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch b/0111-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch new file mode 100644 index 0000000..86e48e4 --- /dev/null +++ b/0111-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch @@ -0,0 +1,53 @@ +From 811b51426d9e7819e6498d4dad0d6ac744a8e5d0 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 da417c7..57dd070 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/0112-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch b/0112-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch new file mode 100644 index 0000000..4bd6ede --- /dev/null +++ b/0112-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch @@ -0,0 +1,58 @@ +From 1582699fb9f748f9f91b015ef311f93bf5a95f5d 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 aa1880c..46a4d8c 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1568,16 +1568,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); +@@ -1608,8 +1607,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) +@@ -1636,10 +1633,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/0113-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch b/0113-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch new file mode 100644 index 0000000..e654a87 --- /dev/null +++ b/0113-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch @@ -0,0 +1,112 @@ +From df750f462929ba85a61dbdd6a4020cb4b2ee68d0 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 05da56b..5545993 100644 +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -643,22 +643,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[] = { +@@ -679,10 +678,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/0114-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch b/0114-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch new file mode 100644 index 0000000..5c921d1 --- /dev/null +++ b/0114-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch @@ -0,0 +1,49 @@ +From d42ac36363ef9e3d3963c2c31fa7122492dbaf0e 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 aac7f83..c23facb 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/0115-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch b/0115-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch new file mode 100644 index 0000000..6c54e1b --- /dev/null +++ b/0115-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch @@ -0,0 +1,49 @@ +From 2bb10b85ffa655f91a4777da4f7a5534ee4c266c 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 bac8421..6895146 100644 +--- a/hw/virtio/virtio-rng.c ++++ b/hw/virtio/virtio-rng.c +@@ -184,16 +184,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); + + qemu_del_timer(vrng->rate_limit_timer); + qemu_free_timer(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[] = { +@@ -205,10 +203,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/0116-virtio-pci-add-device_unplugged-callback.patch b/0116-virtio-pci-add-device_unplugged-callback.patch new file mode 100644 index 0000000..e96fc3b --- /dev/null +++ b/0116-virtio-pci-add-device_unplugged-callback.patch @@ -0,0 +1,59 @@ +From cb2282d55ee34d04a67d74111d69ab098f765680 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 6fd6d6d..242ec3e 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -1000,6 +1000,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); +@@ -1014,9 +1023,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) +@@ -1550,6 +1557,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/0201-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch b/0201-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch new file mode 100644 index 0000000..b31f925 --- /dev/null +++ b/0201-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch @@ -0,0 +1,81 @@ +From 411a7e4ad457f7f3c9f1d02ef9f726ce13a35f08 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 6 Sep 2013 12:32:25 +0200 +Subject: [PATCH] qcow2: Pass discard type to qcow2_discard_clusters() + +The function will be used internally instead of only being called for +guest discard requests. + +Signed-off-by: Kevin Wolf +--- + block/qcow2-cluster.c | 8 ++++---- + block/qcow2.c | 2 +- + block/qcow2.h | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c +index cca76d4..8c3185d 100644 +--- a/block/qcow2-cluster.c ++++ b/block/qcow2-cluster.c +@@ -1317,7 +1317,7 @@ int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) + * clusters. + */ + static int discard_single_l2(BlockDriverState *bs, uint64_t offset, +- unsigned int nb_clusters) ++ unsigned int nb_clusters, enum qcow2_discard_type type) + { + BDRVQcowState *s = bs->opaque; + uint64_t *l2_table; +@@ -1346,7 +1346,7 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset, + l2_table[l2_index + i] = cpu_to_be64(0); + + /* Then decrease the refcount */ +- qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST); ++ qcow2_free_any_clusters(bs, old_offset, 1, type); + } + + ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); +@@ -1358,7 +1358,7 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset, + } + + int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset, +- int nb_sectors) ++ int nb_sectors, enum qcow2_discard_type type) + { + BDRVQcowState *s = bs->opaque; + uint64_t end_offset; +@@ -1381,7 +1381,7 @@ int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset, + + /* Each L2 table is handled by its own loop iteration */ + while (nb_clusters > 0) { +- ret = discard_single_l2(bs, offset, nb_clusters); ++ ret = discard_single_l2(bs, offset, nb_clusters, type); + if (ret < 0) { + goto fail; + } +diff --git a/block/qcow2.c b/block/qcow2.c +index 7f7282e..16e45a0 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -1506,7 +1506,7 @@ static coroutine_fn int qcow2_co_discard(BlockDriverState *bs, + + qemu_co_mutex_lock(&s->lock); + ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS, +- nb_sectors); ++ nb_sectors, QCOW2_DISCARD_REQUEST); + qemu_co_mutex_unlock(&s->lock); + return ret; + } +diff --git a/block/qcow2.h b/block/qcow2.h +index dba9771..52cf193 100644 +--- a/block/qcow2.h ++++ b/block/qcow2.h +@@ -405,7 +405,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, + + int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m); + int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset, +- int nb_sectors); ++ int nb_sectors, enum qcow2_discard_type type); + int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors); + + /* qcow2-snapshot.c functions */ diff --git a/0202-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch b/0202-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch new file mode 100644 index 0000000..cb0e92c --- /dev/null +++ b/0202-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch @@ -0,0 +1,73 @@ +From 16d78f7cd9e1455ebb0599706ba5badfa3ee4fdc Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 6 Sep 2013 12:32:26 +0200 +Subject: [PATCH] qcow2: Discard VM state in active L1 after creating snapshot + +During savevm, the VM state is written to the active L1 of the image and +then a snapshot is taken. After that, the VM state isn't needed any more +in the active L1 and should be discarded. This is implemented by this +patch. + +The impact of not discarding the VM state is that a snapshot can never +become smaller than any previous snapshot (because it would be padded +with old VM state), and more importantly that future savevm operations +cause unnecessary COWs (with associated flushes), which makes subsequent +snapshots much slower. + +Signed-off-by: Kevin Wolf +--- + block/qcow2-snapshot.c | 7 +++++++ + block/qcow2.c | 5 ----- + block/qcow2.h | 5 +++++ + 3 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c +index 0caac90..ae33b45 100644 +--- a/block/qcow2-snapshot.c ++++ b/block/qcow2-snapshot.c +@@ -401,6 +401,13 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) + + g_free(old_snapshot_list); + ++ /* The VM state isn't needed any more in the active L1 table; in fact, it ++ * hurts by causing expensive COW for the next snapshot. */ ++ qcow2_discard_clusters(bs, qcow2_vm_state_offset(s), ++ align_offset(sn->vm_state_size, s->cluster_size) ++ >> BDRV_SECTOR_BITS, ++ QCOW2_DISCARD_NEVER); ++ + #ifdef DEBUG_ALLOC + { + BdrvCheckResult result = {0}; +diff --git a/block/qcow2.c b/block/qcow2.c +index 16e45a0..f63c2cb 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -1666,11 +1666,6 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs) + return 0; + } + +-static int64_t qcow2_vm_state_offset(BDRVQcowState *s) +-{ +- return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); +-} +- + static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) + { + BDRVQcowState *s = bs->opaque; +diff --git a/block/qcow2.h b/block/qcow2.h +index 52cf193..da61d18 100644 +--- a/block/qcow2.h ++++ b/block/qcow2.h +@@ -324,6 +324,11 @@ static inline int64_t align_offset(int64_t offset, int n) + return offset; + } + ++static inline int64_t qcow2_vm_state_offset(BDRVQcowState *s) ++{ ++ return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); ++} ++ + static inline int qcow2_get_cluster_type(uint64_t l2_entry) + { + if (l2_entry & QCOW_OFLAG_COMPRESSED) { diff --git a/0203-hw-9pfs-Fix-errno-value-for-xattr-functions.patch b/0203-hw-9pfs-Fix-errno-value-for-xattr-functions.patch new file mode 100644 index 0000000..cd7b42f --- /dev/null +++ b/0203-hw-9pfs-Fix-errno-value-for-xattr-functions.patch @@ -0,0 +1,68 @@ +From 6f7e1d2bddb5a0a1c65f6f02467460d6edbcc901 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 90ae565..3fae557 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/qemu.spec b/qemu.spec index 11201f2..4e0ceee 100644 --- a/qemu.spec +++ b/qemu.spec @@ -139,7 +139,7 @@ Summary: QEMU is a FAST! processor emulator Name: qemu Version: 1.6.0 -Release: 8%{?dist} +Release: 9%{?dist} Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD Group: Development/Tools @@ -180,24 +180,88 @@ Source12: bridge.conf # qemu-kvm back compat wrapper Source13: qemu-kvm.sh +# Rebase to pending 1.6.1 stable +Patch0001: 0001-block-ensure-bdrv_drain_all-works-during-bdrv_delete.patch +Patch0002: 0002-gdbstub-Fix-gdb_register_coprocessor-register-counti.patch +Patch0003: 0003-target-ppc-fix-bit-extraction-for-FPBF-and-FPL.patch +Patch0004: 0004-rdma-silly-ipv6-bugfix.patch +Patch0005: 0005-scripts-qapi.py-Avoid-syntax-not-supported-by-Python.patch +Patch0006: 0006-usb-dev-hid-Modified-usb-tablet-category-from-Misc-t.patch +Patch0007: 0007-scsi-Fix-scsi_bus_legacy_add_drive-scsi-generic-with.patch +Patch0008: 0008-pc-fix-regression-for-64-bit-PCI-memory.patch +Patch0009: 0009-pseries-Fix-stalls-on-hypervisor-virtual-console.patch +Patch0010: 0010-virtio-virtqueue_get_avail_bytes-fix-desc_pa-when-lo.patch +Patch0011: 0011-xhci-fix-endpoint-interval-calculation.patch +Patch0012: 0012-Revert-usb-hub-report-status-changes-only-once.patch +Patch0013: 0013-block-expect-errors-from-bdrv_co_is_allocated.patch +Patch0014: 0014-target-i386-fix-disassembly-with-PAE-1-PG-0.patch +Patch0015: 0015-adlib-sort-offsets-in-portio-registration.patch +Patch0016: 0016-exec-fix-writing-to-MMIO-area-with-non-power-of-two-.patch +Patch0017: 0017-virtio_pci-fix-level-interrupts-with-irqfd.patch +Patch0018: 0018-exec-always-use-MADV_DONTFORK.patch +Patch0019: 0019-xhci-reset-port-when-disabling-slot.patch +Patch0020: 0020-usb-parallelize-usb3-streams.patch +Patch0021: 0021-w32-Fix-access-to-host-devices-regression.patch +Patch0022: 0022-memory-Provide-separate-handling-of-unassigned-io-po.patch +Patch0023: 0023-Revert-memory-Return-1-again-on-reads-from-unsigned-.patch +Patch0024: 0024-exec-check-offset_within_address_space-for-register-.patch +Patch0025: 0025-ne2000-mark-I-O-as-LITTLE_ENDIAN.patch +Patch0026: 0026-ehci-save-device-pointer-in-EHCIState.patch +Patch0027: 0027-qxl-fix-local-renderer.patch +Patch0028: 0028-pc-Initializing-ram_memory-under-Xen.patch +Patch0029: 0029-pc_q35-Initialize-Xen.patch +Patch0030: 0030-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch +Patch0031: 0031-pcnet-pci-mark-I-O-and-MMIO-as-LITTLE_ENDIAN.patch +Patch0032: 0032-chardev-fix-pty_chr_timer.patch +Patch0033: 0033-kvmvapic-Catch-invalid-ROM-size.patch +Patch0034: 0034-kvmvapic-Enter-inactive-state-on-hardware-reset.patch +Patch0035: 0035-kvmvapic-Clear-also-physical-ROM-address-when-enteri.patch +Patch0036: 0036-tci-Fix-qemu-alpha-on-32-bit-hosts-wrong-assertions.patch +Patch0037: 0037-blockdev-do-not-default-cache.no-flush-to-true.patch +Patch0038: 0038-virtio-blk-do-not-relay-a-previous-driver-s-WCE-conf.patch +Patch0039: 0039-xhci-emulate-intr-endpoint-intervals-correctly.patch +Patch0040: 0040-iov-avoid-orig_len-may-be-used-unitialized-warning.patch +Patch0041: 0041-tap-Use-numbered-tap-tun-devices-on-all-BSD-OS-s.patch +Patch0042: 0042-rbd-avoid-qemu_rbd_snap_list-memory-leaks.patch +Patch0043: 0043-vmdk-fix-cluster-size-check-for-flat-extents.patch +Patch0044: 0044-piix4-disable-io-on-reset.patch +Patch0045: 0045-coroutine-add-.-configure-disable-coroutine-pool.patch +Patch0046: 0046-qemu-Adjust-qemu-wakeup.patch +Patch0047: 0047-qemu-Add-qemu-xen-logic-for-Xen-HVM-S3-resume.patch +Patch0048: 0048-scsi-Allocate-SCSITargetReq-r-buf-dynamically.patch +Patch0049: 0049-Update-VERSION-for-1.6.1-release.patch + # qemu-kvm migration compat (not for upstream, drop by Fedora 21?) -Patch0001: 0001-Fix-migration-from-qemu-kvm.patch -# Fix qmp capabilities calls on i686 (bz #1003162) -# Patch posted upstream -Patch0002: 0002-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch +Patch0101: 0101-Fix-migration-from-qemu-kvm.patch # Fix crash with -M isapc -cpu Haswell (bz #986790) -Patch0003: 0003-isapc-disable-kvmvapic.patch +Patch0102: 0102-isapc-disable-kvmvapic.patch # Fix crash in lsi_soft_reset (bz #1000947) # Patches posted upstream -Patch0004: 0004-pci-do-not-export-pci_bus_reset.patch -Patch0005: 0005-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch -Patch0006: 0006-qdev-switch-reset-to-post-order.patch -# Fix -vga qxl with -display vnc (bz #948717) -# Patch posted upstream -Patch0007: 0007-qxl-fix-local-renderer.patch -# Fix USB crash when installing reactos (bz #1005495) +Patch0103: 0103-pci-do-not-export-pci_bus_reset.patch +Patch0104: 0104-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch +Patch0105: 0105-qdev-switch-reset-to-post-order.patch +# CVE-2013-4377: Fix crash when unplugging virtio devices (bz #1012633, +# bz #1012641) +# Patches posted upstream +Patch0106: 0106-virtio-bus-remove-vdev-field.patch +Patch0107: 0107-virtio-pci-remove-vdev-field.patch +Patch0108: 0108-virtio-ccw-remove-vdev-field.patch +Patch0109: 0109-virtio-bus-cleanup-plug-unplug-interface.patch +Patch0110: 0110-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch +Patch0111: 0111-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch +Patch0112: 0112-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch +Patch0113: 0113-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch +Patch0114: 0114-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch +Patch0115: 0115-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch +Patch0116: 0116-virtio-pci-add-device_unplugged-callback.patch + +# Fix 'new snapshot' slowness after the first snap (bz #988436) +# Patches queued for upstream +Patch0201: 0201-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch +Patch0202: 0202-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch +# Fix 9pfs xattrs on kernel 3.11 (bz #1013676) # Patch posted upstream -Patch0008: 0008-ehci-save-device-pointer-in-EHCIState.patch +Patch0203: 0203-hw-9pfs-Fix-errno-value-for-xattr-functions.patch BuildRequires: SDL-devel BuildRequires: zlib-devel @@ -710,24 +774,88 @@ CAC emulation development files. %prep %setup -q -# qemu-kvm migration compat (not for upstream, drop by Fedora 21?) +# Rebase to pending 1.6.1 stable %patch0001 -p1 -# Fix qmp capabilities calls on i686 (bz #1003162) -# Patch posted upstream %patch0002 -p1 -# Fix crash with -M isapc -cpu Haswell (bz #986790) %patch0003 -p1 -# Fix crash in lsi_soft_reset (bz #1000947) -# Patches posted upstream %patch0004 -p1 %patch0005 -p1 %patch0006 -p1 -# Fix -vga qxl with -display vnc (bz #948717) -# Patch posted upstream %patch0007 -p1 -# Fix USB crash when installing reactos (bz #1005495) -# Patch posted upstream %patch0008 -p1 +%patch0009 -p1 +%patch0010 -p1 +%patch0011 -p1 +%patch0012 -p1 +%patch0013 -p1 +%patch0014 -p1 +%patch0015 -p1 +%patch0016 -p1 +%patch0017 -p1 +%patch0018 -p1 +%patch0019 -p1 +%patch0020 -p1 +%patch0021 -p1 +%patch0022 -p1 +%patch0023 -p1 +%patch0024 -p1 +%patch0025 -p1 +%patch0026 -p1 +%patch0027 -p1 +%patch0028 -p1 +%patch0029 -p1 +%patch0030 -p1 +%patch0031 -p1 +%patch0032 -p1 +%patch0033 -p1 +%patch0034 -p1 +%patch0035 -p1 +%patch0036 -p1 +%patch0037 -p1 +%patch0038 -p1 +%patch0039 -p1 +%patch0040 -p1 +%patch0041 -p1 +%patch0042 -p1 +%patch0043 -p1 +%patch0044 -p1 +%patch0045 -p1 +%patch0046 -p1 +%patch0047 -p1 +%patch0048 -p1 +%patch0049 -p1 + +# qemu-kvm migration compat (not for upstream, drop by Fedora 21?) +%patch0101 -p1 +# Fix crash with -M isapc -cpu Haswell (bz #986790) +%patch0102 -p1 +# Fix crash in lsi_soft_reset (bz #1000947) +# Patches posted upstream +%patch0103 -p1 +%patch0104 -p1 +%patch0105 -p1 +# CVE-2013-4377: Fix crash when unplugging virtio devices (bz #1012633, +# bz #1012641) +# Patches posted upstream +%patch0106 -p1 +%patch0107 -p1 +%patch0108 -p1 +%patch0109 -p1 +%patch0110 -p1 +%patch0111 -p1 +%patch0112 -p1 +%patch0113 -p1 +%patch0114 -p1 +%patch0115 -p1 +%patch0116 -p1 + +# Fix 'new snapshot' slowness after the first snap (bz #988436) +# Patches queued for upstream +%patch0201 -p1 +%patch0202 -p1 +# Fix 9pfs xattrs on kernel 3.11 (bz #1013676) +# Patch posted upstream +%patch0203 -p1 %build @@ -1436,6 +1564,15 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* 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) + * 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)