QEMU is a FAST! processor emulator
CentOS Sources
2015-11-19 05bba06e575829071bce813e12709f9ec477f120
import qemu-kvm-1.5.3-105.el7
145 files added
17 files modified
17227 ■■■■■ changed files
SOURCES/kvm-CVE-2015-1779-incrementally-decode-websocket-frames.patch 16 ●●●● patch | view | raw | blame | history
SOURCES/kvm-CVE-2015-1779-limit-size-of-HTTP-headers-from-websoc.patch 16 ●●●● patch | view | raw | blame | history
SOURCES/kvm-Drop-superfluous-conditionals-around-g_strdup.patch 141 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-Handle-bi-directional-communication-for-fd-migration.patch 89 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-Python-lang-gdb-script-to-extract-x86_64-guest-vmcor.patch 555 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-Remove-redhat-extensions-from-qmp-events.txt.patch 64 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-Restore-atapi_dma-flag-across-migration.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-ahci.c-mask-unused-flags-when-reading-size-PRDT-DBC.patch 92 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-always-update-the-MPX-model-specific-register.patch 58 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-atapi-migration-Throw-recoverable-error-to-avoid-rec.patch 118 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-atomics-add-explicit-compiler-fence-in-__atomic-memo.patch 8 ●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Add-Error-argument-to-bdrv_refresh_limits.patch 307 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Add-qemu_-try_-blockalign0.patch 81 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Allow-JSON-filenames.patch 89 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Catch-bs-drv-in-bdrv_check.patch 48 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Don-t-probe-for-unknown-backing-file-format.patch 203 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Drop-superfluous-conditionals-around-g_free.patch 75 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Fix-NULL-deference-for-unaligned-write-if-qiov.patch 174 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Introduce-qemu_try_blockalign.patch 156 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Print-its-file-name-if-backing-file-opening-fa.patch 172 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Propagate-error-in-bdrv_img_create.patch 55 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-Respect-underlying-file-s-EOF.patch 65 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-coverity-fix-check-return-value-for-fcntl-in-g.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-curl-Don-t-lose-original-error-when-a-connecti.patch 100 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-curl-Implement-the-libcurl-timer-callback-inte.patch 200 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-curl-Improve-type-safety-of-s-timeout.patch 88 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-qemu-iotests-add-check-for-multiplication-over.patch 121 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-ssh-Drop-superfluous-libssh2_session_last_errn.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-ssh-Propagate-errors-through-authenticate.patch 106 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-ssh-Propagate-errors-through-check_host_key.patch 193 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-ssh-Propagate-errors-through-connect_to_ssh.patch 143 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-ssh-Propagate-errors-to-open-and-create-method.patch 158 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-update-test-070-for-vhdx.patch 56 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-vpc-prevent-overflow-if-max_table_entries-0x40.patch 94 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block.curl-adding-timeout-option.patch 102 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-build-reenable-local-builds-to-pass-enable-debug-RHE.patch 80 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-configure-Add-handling-code-for-AArch64-targets.patch 68 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-configure-Add-support-for-tcmalloc.patch 129 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-configure-Require-libfdt-for-arm-ppc-microblaze-soft.patch 69 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-configure-permit-compilation-on-arm-aarch64.patch 67 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Add-sslverify-option.patch 88 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Allow-a-cookie-or-cookies-to-be-sent-with-http-.patch 126 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Eliminate-unnecessary-use-of-curl_multi_socket_.patch 142 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Ensure-all-informationals-are-checked-for-compl.patch 107 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Fix-build-when-curl_multi_socket_action-isn-t-a.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Fix-hang-reading-from-slow-connections.patch 49 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Fix-long-line.patch 42 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Fix-return-from-curl_read_cb-with-invalid-state.patch 53 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Handle-failure-for-potentially-large-allocation.patch 53 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Remove-broken-parsing-of-options-from-url.patch 129 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Remove-erroneous-sleep-waiting-for-curl-complet.patch 53 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Remove-unnecessary-explicit-calls-to-internal-e.patch 66 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Remove-unnecessary-use-of-goto.patch 101 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Replaced-old-error-handling-with-error-reportin.patch 42 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-The-macro-that-you-have-to-uncomment-to-get-deb.patch 41 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-Whitespace-only-changes.patch 44 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-curl-refuse-to-open-URL-from-HTTP-server-without-ran.patch 112 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-fdc-force-the-fifo-access-to-be-in-bounds-of-the-all.patch 18 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-i8254-fix-out-of-bounds-memory-access-in-pit_ioport_.patch 5 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-ide-Check-array-bounds-before-writing-to-io_buffer-C.patch 14 ●●●● patch | view | raw | blame | history
SOURCES/kvm-ide-Check-validity-of-logical-block-size.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-ide-Clear-DRQ-after-handling-all-expected-accesses.patch 14 ●●●● patch | view | raw | blame | history
SOURCES/kvm-ide-Correct-handling-of-malformed-short-PRDTs.patch 333 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-ide-atapi-Fix-START-STOP-UNIT-command-completion.patch 8 ●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Add-more-tests-for-qcow2-corruption.patch 162 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Add-test-for-image-header-overlap.patch 70 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Add-test-for-non-existing-backing-file.patch 120 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Add-test-for-potentially-damaging-repairs.patch 316 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Add-test-for-qcow2-L1-table-update.patch 131 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Add-tests-for-more-corruption-cases.patch 94 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Add-tests-for-refcount-table-growth.patch 184 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iotests-Fix-test-outputs.patch 147 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-iscsi-Refuse-to-open-as-writable-if-the-LUN-is-write.patch 103 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-main-set-current_machine-before-calling-machine-init.patch 67 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-mc146818rtc-add-rtc-reset-reinjection-QMP-command.patch 156 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-migration_cancel-shutdown-migration-socket.patch 64 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-pc_sysfw-prevent-pflash-and-or-mis-sized-firmware-fo.patch 68 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qapi-block-Add-fatal-to-BLOCK_IMAGE_CORRUPTED.patch 83 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Add-qcow2_signal_corruption.patch 147 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Add-two-more-unalignment-checks.patch 72 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Calculate-refcount-block-entry-count.patch 61 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Catch-bdrv_getlength-error.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Catch-host_offset-for-data-allocation.patch 67 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Check-L1-L2-reftable-entries-for-alignment.patch 215 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Clean-up-after-refcount-rebuild.patch 94 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch 95 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Do-not-overflow-when-writing-an-L1-sector.patch 58 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Do-not-perform-potentially-damaging-repairs.patch 319 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Drop-REFCOUNT_SHIFT.patch 170 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Fix-header-extension-size-check.patch 83 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Fix-header-update-with-overridden-backing-file.patch 288 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Fix-leaks-in-dirty-images.patch 50 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Fix-refcount-blocks-beyond-image-end.patch 117 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Flush-pending-discards-before-allocating-clust.patch 61 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Let-inc_refcounts-resize-the-reftable.patch 168 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Let-inc_refcounts-return-errno.patch 222 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Pass-discard-type-to-qcow2_discard_clusters.patch 96 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Pull-check_refblocks-up.patch 156 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Put-cache-reference-in-error-case.patch 46 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Rebuild-refcount-structure-during-check.patch 374 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Respect-new_block-in-alloc_refcount_block.patch 72 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Reuse-refcount-table-in-calculate_refcounts.patch 66 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Split-fail-code-in-L1-and-L2-checks.patch 111 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Split-qcow2_check_refcounts.patch 289 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Use-int64_t-for-in-memory-reftable-size.patch 62 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Use-qcow2_signal_corruption-for-overlaps.patch 135 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-Use-sizeof-refcount_table.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2-fix-leak-of-Qcow2DiscardRegion-in-update_refco.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qcow2.py-Add-required-padding-for-header-extensions.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qdict-Add-qdict_join.patch 89 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qemu-iotests-Filter-qemu-io-output-in-025.patch 41 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qemu-iotests-Test-unaligned-4k-zero-write.patch 123 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qemu-iotests-Test-unaligned-sub-block-zero-write.patch 101 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qtest-ide-test-disable-flush-test.patch 22 ●●●● patch | view | raw | blame | history
SOURCES/kvm-raw-posix-Fail-gracefully-if-no-working-alignment-is.patch 141 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-rtl8139-avoid-nested-ifs-in-IP-header-parsing-CVE-20.patch 6 ●●●● patch | view | raw | blame | history
SOURCES/kvm-rtl8139-check-IP-Header-Length-field-CVE-2015-5165.patch 6 ●●●● patch | view | raw | blame | history
SOURCES/kvm-rtl8139-check-IP-Total-Length-field-CVE-2015-5165.patch 6 ●●●● patch | view | raw | blame | history
SOURCES/kvm-rtl8139-check-TCP-Data-Offset-field-CVE-2015-5165.patch 6 ●●●● patch | view | raw | blame | history
SOURCES/kvm-rtl8139-drop-tautologous-if-ip-.-statement-CVE-2015-.patch 6 ●●●● patch | view | raw | blame | history
SOURCES/kvm-rtl8139-skip-offload-on-short-Ethernet-IP-header-CVE.patch 6 ●●●● patch | view | raw | blame | history
SOURCES/kvm-rtl8139-skip-offload-on-short-TCP-header-CVE-2015-51.patch 7 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-scsi-disk-fix-cmd.mode-field-typo.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-seccomp-add-timerfd_create-and-timerfd_settime-to-th.patch 88 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-serial-reset-state-at-startup.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-socket-shutdown.patch 151 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-spice-display-fix-segfault-in-qemu_spice_create_upda.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-ssh-Don-t-crash-if-either-host-or-path-is-not-specif.patch 70 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-target-i386-Add-mpx-CPU-feature-name.patch 42 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-target-i386-Avoid-shifting-left-into-sign-bit.patch 399 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-target-i386-Intel-MPX.patch 272 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-target-i386-add-Intel-AVX-512-support.patch 337 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-target-i386-bugfix-of-Intel-MPX.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-target-i386-fix-cpuid-leaf-0x0d.patch 59 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-target-i386-fix-set-of-registers-zeroed-on-reset.patch 94 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-trace-add-qemu_system_powerdown_request-and-qemu_sys.patch 110 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-usb-ccid-add-missing-wakeup-calls.patch 76 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-util-Drop-superfluous-conditionals-around-g_free.patch 177 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-util-Fuse-g_malloc-memset-into-g_new0.patch 40 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-util-uri-Add-overflow-check-to-rfc3986_parse_port.patch 68 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-util-uri-URI-member-path-can-be-null-compare-more-ca.patch 64 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-util-uri-realloc2n-can-t-fail-drop-dead-error-handli.patch 180 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-util-uri-uri_new-can-t-fail-drop-dead-error-handling.patch 113 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-Correction-in-vfio_rom_read-when-attempting-rom.patch 50 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-Do-not-reattempt-a-failed-rom-read.patch 72 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-Fix-overrun-after-readlink-fills-buffer-complet.patch 55 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-Use-vfio-type1-v2-IOMMU-interface.patch 73 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Add-pba_offset-PCI-quirk-for-Chelsio-T5-dev.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Enable-device-request-notification-support.patch 201 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Fix-BAR-size-overflow.patch 57 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Fix-error-path-sign.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Further-fix-BAR-size-overflow.patch 59 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-use-correct-runstate.patch 44 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-warn-if-host-device-rom-can-t-be-read.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-net-drop-assert-on-vm-stop.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-scsi-use-virtqueue_map_sg-when-loading-reques.patch 57 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vmdk-Fix-overflow-if-l1_size-is-0x20000000.patch 62 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vpc-Handle-failure-for-potentially-large-allocations.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-x86-Clear-MTRRs-on-vCPU-reset.patch 65 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-x86-Use-common-variable-range-MTRR-counts.patch 59 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-x86-kvm-Add-MTRR-support-for-kvm_get-put_msrs.patch 213 ●●●●● patch | view | raw | blame | history
SPECS/qemu-kvm.spec 872 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-CVE-2015-1779-incrementally-decode-websocket-frames.patch
@@ -1,15 +1,15 @@
From 2eae7bb4e94710164926c670334a83bf9d347c2f Mon Sep 17 00:00:00 2001
From 67c87cd508385158a8a0fb12a430dd19d2883974 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 22 Sep 2015 17:44:53 +0200
Subject: [PATCH 1/2] CVE-2015-1779: incrementally decode websocket frames
Date: Wed, 20 May 2015 08:39:08 +0200
Subject: [PATCH 1/6] CVE-2015-1779: incrementally decode websocket frames
Message-id: <1442943894-7638-2-git-send-email-kraxel@redhat.com>
Patchwork-id: 67884
O-Subject: [RHEL-7.1.z qemu-kvm PATCH 1/2] CVE-2015-1779: incrementally decode websocket frames
Bugzilla: 1205050
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
Message-id: <1432111149-11644-2-git-send-email-kraxel@redhat.com>
Patchwork-id: 65099
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/2] CVE-2015-1779: incrementally decode websocket frames
Bugzilla: 1206497
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Petr Matousek <pmatouse@redhat.com>
RH-Acked-by: Daniel P. Berrange <berrange@redhat.com>
From: "Daniel P. Berrange" <berrange@redhat.com>
SOURCES/kvm-CVE-2015-1779-limit-size-of-HTTP-headers-from-websoc.patch
@@ -1,16 +1,16 @@
From 7721e2e58f7cd2fcf835800622b8a7e1cdeb4557 Mon Sep 17 00:00:00 2001
From 62121d1bd1f17f5b9822b98f4ee2c9fd159b50e5 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 22 Sep 2015 17:44:54 +0200
Subject: [PATCH 2/2] CVE-2015-1779: limit size of HTTP headers from websockets
Date: Wed, 20 May 2015 08:39:09 +0200
Subject: [PATCH 2/6] CVE-2015-1779: limit size of HTTP headers from websockets
 clients
Message-id: <1442943894-7638-3-git-send-email-kraxel@redhat.com>
Patchwork-id: 67885
O-Subject: [RHEL-7.1.z qemu-kvm PATCH 2/2] CVE-2015-1779: limit size of HTTP headers from websockets clients
Bugzilla: 1205050
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
Message-id: <1432111149-11644-3-git-send-email-kraxel@redhat.com>
Patchwork-id: 65097
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/2] CVE-2015-1779: limit size of HTTP headers from websockets clients
Bugzilla: 1206497
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Petr Matousek <pmatouse@redhat.com>
RH-Acked-by: Daniel P. Berrange <berrange@redhat.com>
From: "Daniel P. Berrange" <berrange@redhat.com>
SOURCES/kvm-Drop-superfluous-conditionals-around-g_strdup.patch
New file
@@ -0,0 +1,141 @@
From beb312b86b7ee776bbaea14d3c7625ec8d2d8402 Mon Sep 17 00:00:00 2001
From: Markus Armbruster <armbru@redhat.com>
Date: Tue, 8 Sep 2015 18:06:19 +0200
Subject: [PATCH 1/7] Drop superfluous conditionals around g_strdup()
Message-id: <1441735585-23432-2-git-send-email-armbru@redhat.com>
Patchwork-id: 67708
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/7] Drop superfluous conditionals around g_strdup()
Bugzilla: 1218919
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 24588100ab39afead7b9a0e9c61182a02320a1b9)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 backends/rng-random.c    |  6 +-----
 hw/tpm/tpm_passthrough.c |  4 +---
 util/uri.c               | 43 +++++++++++++++++--------------------------
 3 files changed, 19 insertions(+), 34 deletions(-)
diff --git a/backends/rng-random.c b/backends/rng-random.c
index 68dfc8a..573a64e 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -88,11 +88,7 @@ static char *rng_random_get_filename(Object *obj, Error **errp)
 {
     RndRandom *s = RNG_RANDOM(obj);
-    if (s->filename) {
-        return g_strdup(s->filename);
-    }
-
-    return NULL;
+    return g_strdup(s->filename);
 }
 static void rng_random_set_filename(Object *obj, const char *filename,
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 56e9e0f..2bf3c6f 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -400,9 +400,7 @@ static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb)
     const char *value;
     value = qemu_opt_get(opts, "cancel-path");
-    if (value) {
-        tb->cancel_path = g_strdup(value);
-    }
+    tb->cancel_path = g_strdup(value);
     value = qemu_opt_get(opts, "path");
     if (!value) {
diff --git a/util/uri.c b/util/uri.c
index e348c17..bbf2832 100644
--- a/util/uri.c
+++ b/util/uri.c
@@ -1736,24 +1736,21 @@ uri_resolve(const char *uri, const char *base) {
     goto done;
     if ((ref->scheme == NULL) && (ref->path == NULL) &&
     ((ref->authority == NULL) && (ref->server == NULL))) {
-    if (bas->scheme != NULL)
-        res->scheme = g_strdup(bas->scheme);
+        res->scheme = g_strdup(bas->scheme);
     if (bas->authority != NULL)
         res->authority = g_strdup(bas->authority);
     else if (bas->server != NULL) {
-        res->server = g_strdup(bas->server);
-        if (bas->user != NULL)
-        res->user = g_strdup(bas->user);
-        res->port = bas->port;
+            res->server = g_strdup(bas->server);
+            res->user = g_strdup(bas->user);
+            res->port = bas->port;
     }
-    if (bas->path != NULL)
-        res->path = g_strdup(bas->path);
-    if (ref->query != NULL)
+        res->path = g_strdup(bas->path);
+        if (ref->query != NULL) {
         res->query = g_strdup (ref->query);
-    else if (bas->query != NULL)
-        res->query = g_strdup(bas->query);
-    if (ref->fragment != NULL)
-        res->fragment = g_strdup(ref->fragment);
+        } else {
+            res->query = g_strdup(bas->query);
+        }
+        res->fragment = g_strdup(ref->fragment);
     goto step_7;
     }
@@ -1767,13 +1764,10 @@ uri_resolve(const char *uri, const char *base) {
     val = uri_to_string(ref);
     goto done;
     }
-    if (bas->scheme != NULL)
-    res->scheme = g_strdup(bas->scheme);
+    res->scheme = g_strdup(bas->scheme);
-    if (ref->query != NULL)
-    res->query = g_strdup(ref->query);
-    if (ref->fragment != NULL)
-    res->fragment = g_strdup(ref->fragment);
+    res->query = g_strdup(ref->query);
+    res->fragment = g_strdup(ref->fragment);
     /*
      * 4) If the authority component is defined, then the reference is a
@@ -1787,20 +1781,17 @@ uri_resolve(const char *uri, const char *base) {
         res->authority = g_strdup(ref->authority);
     else {
         res->server = g_strdup(ref->server);
-        if (ref->user != NULL)
-        res->user = g_strdup(ref->user);
+            res->user = g_strdup(ref->user);
             res->port = ref->port;
     }
-    if (ref->path != NULL)
-        res->path = g_strdup(ref->path);
+        res->path = g_strdup(ref->path);
     goto step_7;
     }
     if (bas->authority != NULL)
     res->authority = g_strdup(bas->authority);
     else if (bas->server != NULL) {
-    res->server = g_strdup(bas->server);
-    if (bas->user != NULL)
-        res->user = g_strdup(bas->user);
+        res->server = g_strdup(bas->server);
+        res->user = g_strdup(bas->user);
     res->port = bas->port;
     }
--
1.8.3.1
SOURCES/kvm-Handle-bi-directional-communication-for-fd-migration.patch
New file
@@ -0,0 +1,89 @@
From 24a9e4d46608ccdcec53eeccc40b7a5d3fb7c9c8 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Fri, 16 Jan 2015 17:35:36 +0100
Subject: [PATCH 04/16] Handle bi-directional communication for fd migration
Message-id: <1421429737-23581-3-git-send-email-dgilbert@redhat.com>
Patchwork-id: 63333
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/3] Handle bi-directional communication for fd migration
Bugzilla: 1086168
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Cristian Klein <cristian.klein@cs.umu.se>
libvirt prefers opening the TCP connection itself, for two reasons.
First, connection failed errors can be detected easier, without having
to parse qemu's error output.
Second, libvirt might be asked to secure the transfer by tunnelling the
communication through an TLS layer.
Therefore, libvirt opens the TCP connection itself and passes an FD to qemu
using QMP and a POSIX-specific mechanism.
Hence, in order to make the reverse-path work in such cases, qemu needs to
distinguish if the transmitted FD is a socket (reverse-path available)
or not (reverse-path might not be available) and use the corresponding
abstraction.
Signed-off-by: Cristian Klein <cristian.klein@cs.umu.se>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 131fe9b843f9a1e55fcbf2457c9cb25c3711b9d8)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 migration-fd.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/migration-fd.c b/migration-fd.c
index 3d4613c..3c98c3c 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -30,13 +30,29 @@
     do { } while (0)
 #endif
+static bool fd_is_socket(int fd)
+{
+    struct stat stat;
+    int ret = fstat(fd, &stat);
+    if (ret == -1) {
+        /* When in doubt say no */
+        return false;
+    }
+    return S_ISSOCK(stat.st_mode);
+}
+
 void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
 {
     int fd = monitor_get_fd(cur_mon, fdname, errp);
     if (fd == -1) {
         return;
     }
-    s->file = qemu_fdopen(fd, "wb");
+
+    if (fd_is_socket(fd)) {
+        s->file = qemu_fopen_socket(fd, "wb");
+    } else {
+        s->file = qemu_fdopen(fd, "wb");
+    }
     migrate_fd_connect(s);
 }
@@ -57,7 +73,11 @@ void fd_start_incoming_migration(const char *infd, Error **errp)
     DPRINTF("Attempting to start an incoming migration via fd\n");
     fd = strtol(infd, NULL, 0);
-    f = qemu_fdopen(fd, "rb");
+    if (fd_is_socket(fd)) {
+        f = qemu_fopen_socket(fd, "rb");
+    } else {
+        f = qemu_fdopen(fd, "rb");
+    }
     if(f == NULL) {
         error_setg_errno(errp, errno, "failed to open the source descriptor");
         return;
--
1.8.3.1
SOURCES/kvm-Python-lang-gdb-script-to-extract-x86_64-guest-vmcor.patch
New file
@@ -0,0 +1,555 @@
From 11d85a217f6b3b15710bbc786adebd943774be09 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Fri, 20 Feb 2015 09:53:20 +0100
Subject: [PATCH 14/16] Python-lang gdb script to extract x86_64 guest vmcore
 from qemu coredump
Message-id: <1424426001-3543-2-git-send-email-lersek@redhat.com>
Patchwork-id: 63908
O-Subject: [RHEL-7.2 qemu-kvm PATCH v2 1/2] Python-lang gdb script to extract x86_64 guest vmcore from qemu coredump
Bugzilla: 828493
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Jeff Nelson <jenelson@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
When qemu dies unexpectedly, for example in response to an explicit
abort() call, or (more importantly) when an external signal is delivered
to it that results in a coredump, sometimes it is useful to extract the
guest vmcore from the qemu process' memory image. The guest vmcore might
help understand an emulation problem in qemu, or help debug the guest.
This script reimplements (and cuts many features of) the
qmp_dump_guest_memory() command in gdb/Python,
  https://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html
working off the saved memory image of the qemu process. The docstring in
the patch (serving as gdb help text) describes the limitations relative to
the QMP command.
Dependencies of qmp_dump_guest_memory() have been reimplemented as needed.
I sought to follow the general structure, sticking to original function
names where possible. However, keeping it simple prevailed in some places.
The patch has been tested with a 4 VCPU, 768 MB, RHEL-6.4
(2.6.32-358.el6.x86_64) guest:
- The script printed
> guest RAM blocks:
> target_start     target_end       host_addr        message count
> ---------------- ---------------- ---------------- ------- -----
> 0000000000000000 00000000000a0000 00007f95d0000000 added       1
> 00000000000a0000 00000000000b0000 00007f960ac00000 added       2
> 00000000000c0000 00000000000ca000 00007f95d00c0000 added       3
> 00000000000ca000 00000000000cd000 00007f95d00ca000 joined      3
> 00000000000cd000 00000000000d0000 00007f95d00cd000 joined      3
> 00000000000d0000 00000000000f0000 00007f95d00d0000 joined      3
> 00000000000f0000 0000000000100000 00007f95d00f0000 joined      3
> 0000000000100000 0000000030000000 00007f95d0100000 joined      3
> 00000000fc000000 00000000fc800000 00007f960ac00000 added       4
> 00000000fffe0000 0000000100000000 00007f9618800000 added       5
> dumping range at 00007f95d0000000 for length 00000000000a0000
> dumping range at 00007f960ac00000 for length 0000000000010000
> dumping range at 00007f95d00c0000 for length 000000002ff40000
> dumping range at 00007f960ac00000 for length 0000000000800000
> dumping range at 00007f9618800000 for length 0000000000020000
- The vmcore was checked with "readelf", comparing the results against a
  vmcore written by qmp_dump_guest_memory():
> --- theirs      2013-09-12 17:38:59.797289404 +0200
> +++ mine        2013-09-12 17:39:03.820289404 +0200
> @@ -27,16 +27,16 @@
>    Type           Offset             VirtAddr           PhysAddr
>                   FileSiz            MemSiz              Flags  Align
>    NOTE           0x0000000000000190 0x0000000000000000 0x0000000000000000
> -                 0x0000000000000ca0 0x0000000000000ca0         0
> -  LOAD           0x0000000000000e30 0x0000000000000000 0x0000000000000000
> +                 0x000000000000001c 0x000000000000001c         0
> +  LOAD           0x00000000000001ac 0x0000000000000000 0x0000000000000000
>                   0x00000000000a0000 0x00000000000a0000         0
> -  LOAD           0x00000000000a0e30 0x0000000000000000 0x00000000000a0000
> +  LOAD           0x00000000000a01ac 0x0000000000000000 0x00000000000a0000
>                   0x0000000000010000 0x0000000000010000         0
> -  LOAD           0x00000000000b0e30 0x0000000000000000 0x00000000000c0000
> +  LOAD           0x00000000000b01ac 0x0000000000000000 0x00000000000c0000
>                   0x000000002ff40000 0x000000002ff40000         0
> -  LOAD           0x000000002fff0e30 0x0000000000000000 0x00000000fc000000
> +  LOAD           0x000000002fff01ac 0x0000000000000000 0x00000000fc000000
>                   0x0000000000800000 0x0000000000800000         0
> -  LOAD           0x00000000307f0e30 0x0000000000000000 0x00000000fffe0000
> +  LOAD           0x00000000307f01ac 0x0000000000000000 0x00000000fffe0000
>                   0x0000000000020000 0x0000000000020000         0
>
>  There is no dynamic section in this file.
> @@ -47,13 +47,6 @@
>
>  No version information found in this file.
>
> -Notes at offset 0x00000190 with length 0x00000ca0:
> +Notes at offset 0x00000190 with length 0x0000001c:
>    Owner                Data size       Description
> -  CORE         0x00000150      NT_PRSTATUS (prstatus structure)
> -  CORE         0x00000150      NT_PRSTATUS (prstatus structure)
> -  CORE         0x00000150      NT_PRSTATUS (prstatus structure)
> -  CORE         0x00000150      NT_PRSTATUS (prstatus structure)
> -  QEMU         0x000001b0      Unknown note type: (0x00000000)
> -  QEMU         0x000001b0      Unknown note type: (0x00000000)
> -  QEMU         0x000001b0      Unknown note type: (0x00000000)
> -  QEMU         0x000001b0      Unknown note type: (0x00000000)
> +  NONE         0x00000005      Unknown note type: (0x00000000)
- The vmcore was checked with "crash" too, again comparing the results
  against a vmcore written by qmp_dump_guest_memory():
> --- guest.vmcore.log2   2013-09-12 17:52:27.074289201 +0200
> +++ example.dump.log2   2013-09-12 17:52:15.904289203 +0200
> @@ -22,11 +22,11 @@
>  This GDB was configured as "x86_64-unknown-linux-gnu"...
>
>       KERNEL: /usr/lib/debug/lib/modules/2.6.32-358.el6.x86_64/vmlinux
> -    DUMPFILE: /home/lacos/tmp/guest.vmcore
> +    DUMPFILE: /home/lacos/tmp/example.dump
>          CPUS: 4
> -        DATE: Thu Sep 12 17:16:11 2013
> -      UPTIME: 00:01:09
> -LOAD AVERAGE: 0.07, 0.03, 0.00
> +        DATE: Thu Sep 12 17:17:41 2013
> +      UPTIME: 00:00:38
> +LOAD AVERAGE: 0.18, 0.05, 0.01
>         TASKS: 130
>      NODENAME: localhost.localdomain
>       RELEASE: 2.6.32-358.el6.x86_64
> @@ -38,12 +38,12 @@
>       COMMAND: "swapper"
>          TASK: ffffffff81a8d020  (1 of 4)  [THREAD_INFO: ffffffff81a00000]
>           CPU: 0
> -       STATE: TASK_RUNNING (PANIC)
> +       STATE: TASK_RUNNING (ACTIVE)
> +     WARNING: panic task not found
>
>  crash> bt
>  PID: 0      TASK: ffffffff81a8d020  CPU: 0   COMMAND: "swapper"
> - #0 [ffffffff81a01ed0] default_idle at ffffffff8101495d
> - #1 [ffffffff81a01ef0] cpu_idle at ffffffff81009fc6
> + #0 [ffffffff81a01ef0] cpu_idle at ffffffff81009fc6
>  crash> task ffffffff81a8d020
>  PID: 0      TASK: ffffffff81a8d020  CPU: 0   COMMAND: "swapper"
>  struct task_struct {
> @@ -75,7 +75,7 @@
>        prev = 0xffffffff81a8d080
>      },
>      on_rq = 0,
> -    exec_start = 8618466836,
> +    exec_start = 7469214014,
>      sum_exec_runtime = 0,
>      vruntime = 0,
>      prev_sum_exec_runtime = 0,
> @@ -149,7 +149,7 @@
>    },
>    tasks = {
>      next = 0xffff88002d621948,
> -    prev = 0xffff880029618f28
> +    prev = 0xffff880023b74488
>    },
>    pushable_tasks = {
>      prio = 140,
> @@ -165,7 +165,7 @@
>      }
>    },
>    mm = 0x0,
> -  active_mm = 0xffff88002929b780,
> +  active_mm = 0xffff8800297eb980,
>    exit_state = 0,
>    exit_code = 0,
>    exit_signal = 0,
> @@ -177,7 +177,7 @@
>    sched_reset_on_fork = 0,
>    pid = 0,
>    tgid = 0,
> -  stack_canary = 2483693585637059287,
> +  stack_canary = 7266362296181431986,
>    real_parent = 0xffffffff81a8d020,
>    parent = 0xffffffff81a8d020,
>    children = {
> @@ -224,14 +224,14 @@
>    set_child_tid = 0x0,
>    clear_child_tid = 0x0,
>    utime = 0,
> -  stime = 3,
> +  stime = 2,
>    utimescaled = 0,
> -  stimescaled = 3,
> +  stimescaled = 2,
>    gtime = 0,
>    prev_utime = 0,
>    prev_stime = 0,
>    nvcsw = 0,
> -  nivcsw = 1000,
> +  nivcsw = 1764,
>    start_time = {
>      tv_sec = 0,
>      tv_nsec = 0
- <name_dropping>I asked for Dave Anderson's help with verifying the
  extracted vmcore, and his comments make me think I should post
  this.</name_dropping>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 3e16d14fd93ca6059134ba6b4f65c1c3e4cd3a18)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 scripts/dump-guest-memory.py | 339 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 339 insertions(+)
 create mode 100644 scripts/dump-guest-memory.py
diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
new file mode 100644
index 0000000..1ed8b67
--- /dev/null
+++ b/scripts/dump-guest-memory.py
@@ -0,0 +1,339 @@
+# This python script adds a new gdb command, "dump-guest-memory". It
+# should be loaded with "source dump-guest-memory.py" at the (gdb)
+# prompt.
+#
+# Copyright (C) 2013, Red Hat, Inc.
+#
+# Authors:
+#   Laszlo Ersek <lersek@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later. See
+# the COPYING file in the top-level directory.
+#
+# The leading docstring doesn't have idiomatic Python formatting. It is
+# printed by gdb's "help" command (the first line is printed in the
+# "help data" summary), and it should match how other help texts look in
+# gdb.
+
+import struct
+
+class DumpGuestMemory(gdb.Command):
+    """Extract guest vmcore from qemu process coredump.
+
+The sole argument is FILE, identifying the target file to write the
+guest vmcore to.
+
+This GDB command reimplements the dump-guest-memory QMP command in
+python, using the representation of guest memory as captured in the qemu
+coredump. The qemu process that has been dumped must have had the
+command line option "-machine dump-guest-core=on".
+
+For simplicity, the "paging", "begin" and "end" parameters of the QMP
+command are not supported -- no attempt is made to get the guest's
+internal paging structures (ie. paging=false is hard-wired), and guest
+memory is always fully dumped.
+
+Only x86_64 guests are supported.
+
+The CORE/NT_PRSTATUS and QEMU notes (that is, the VCPUs' statuses) are
+not written to the vmcore. Preparing these would require context that is
+only present in the KVM host kernel module when the guest is alive. A
+fake ELF note is written instead, only to keep the ELF parser of "crash"
+happy.
+
+Dependent on how busted the qemu process was at the time of the
+coredump, this command might produce unpredictable results. If qemu
+deliberately called abort(), or it was dumped in response to a signal at
+a halfway fortunate point, then its coredump should be in reasonable
+shape and this command should mostly work."""
+
+    TARGET_PAGE_SIZE = 0x1000
+    TARGET_PAGE_MASK = 0xFFFFFFFFFFFFF000
+
+    # Various ELF constants
+    EM_X86_64   = 62        # AMD x86-64 target machine
+    ELFDATA2LSB = 1         # little endian
+    ELFCLASS64  = 2
+    ELFMAG      = "\x7FELF"
+    EV_CURRENT  = 1
+    ET_CORE     = 4
+    PT_LOAD     = 1
+    PT_NOTE     = 4
+
+    # Special value for e_phnum. This indicates that the real number of
+    # program headers is too large to fit into e_phnum. Instead the real
+    # value is in the field sh_info of section 0.
+    PN_XNUM = 0xFFFF
+
+    # Format strings for packing and header size calculation.
+    ELF64_EHDR = ("4s" # e_ident/magic
+                  "B"  # e_ident/class
+                  "B"  # e_ident/data
+                  "B"  # e_ident/version
+                  "B"  # e_ident/osabi
+                  "8s" # e_ident/pad
+                  "H"  # e_type
+                  "H"  # e_machine
+                  "I"  # e_version
+                  "Q"  # e_entry
+                  "Q"  # e_phoff
+                  "Q"  # e_shoff
+                  "I"  # e_flags
+                  "H"  # e_ehsize
+                  "H"  # e_phentsize
+                  "H"  # e_phnum
+                  "H"  # e_shentsize
+                  "H"  # e_shnum
+                  "H"  # e_shstrndx
+                 )
+    ELF64_PHDR = ("I"  # p_type
+                  "I"  # p_flags
+                  "Q"  # p_offset
+                  "Q"  # p_vaddr
+                  "Q"  # p_paddr
+                  "Q"  # p_filesz
+                  "Q"  # p_memsz
+                  "Q"  # p_align
+                 )
+
+    def __init__(self):
+        super(DumpGuestMemory, self).__init__("dump-guest-memory",
+                                              gdb.COMMAND_DATA,
+                                              gdb.COMPLETE_FILENAME)
+        self.uintptr_t     = gdb.lookup_type("uintptr_t")
+        self.elf64_ehdr_le = struct.Struct("<%s" % self.ELF64_EHDR)
+        self.elf64_phdr_le = struct.Struct("<%s" % self.ELF64_PHDR)
+
+    def int128_get64(self, val):
+        assert (val["hi"] == 0)
+        return val["lo"]
+
+    def qtailq_foreach(self, head, field_str):
+        var_p = head["tqh_first"]
+        while (var_p != 0):
+            var = var_p.dereference()
+            yield var
+            var_p = var[field_str]["tqe_next"]
+
+    def qemu_get_ram_block(self, ram_addr):
+        ram_blocks = gdb.parse_and_eval("ram_list.blocks")
+        for block in self.qtailq_foreach(ram_blocks, "next"):
+            if (ram_addr - block["offset"] < block["length"]):
+                return block
+        raise gdb.GdbError("Bad ram offset %x" % ram_addr)
+
+    def qemu_get_ram_ptr(self, ram_addr):
+        block = self.qemu_get_ram_block(ram_addr)
+        return block["host"] + (ram_addr - block["offset"])
+
+    def memory_region_get_ram_ptr(self, mr):
+        if (mr["alias"] != 0):
+            return (self.memory_region_get_ram_ptr(mr["alias"].dereference()) +
+                    mr["alias_offset"])
+        return self.qemu_get_ram_ptr(mr["ram_addr"] & self.TARGET_PAGE_MASK)
+
+    def guest_phys_blocks_init(self):
+        self.guest_phys_blocks = []
+
+    def guest_phys_blocks_append(self):
+        print "guest RAM blocks:"
+        print ("target_start     target_end       host_addr        message "
+               "count")
+        print ("---------------- ---------------- ---------------- ------- "
+               "-----")
+
+        current_map_p = gdb.parse_and_eval("address_space_memory.current_map")
+        current_map = current_map_p.dereference()
+        for cur in range(current_map["nr"]):
+            flat_range   = (current_map["ranges"] + cur).dereference()
+            mr           = flat_range["mr"].dereference()
+
+            # we only care about RAM
+            if (not mr["ram"]):
+                continue
+
+            section_size = self.int128_get64(flat_range["addr"]["size"])
+            target_start = self.int128_get64(flat_range["addr"]["start"])
+            target_end   = target_start + section_size
+            host_addr    = (self.memory_region_get_ram_ptr(mr) +
+                            flat_range["offset_in_region"])
+            predecessor = None
+
+            # find continuity in guest physical address space
+            if (len(self.guest_phys_blocks) > 0):
+                predecessor = self.guest_phys_blocks[-1]
+                predecessor_size = (predecessor["target_end"] -
+                                    predecessor["target_start"])
+
+                # the memory API guarantees monotonically increasing
+                # traversal
+                assert (predecessor["target_end"] <= target_start)
+
+                # we want continuity in both guest-physical and
+                # host-virtual memory
+                if (predecessor["target_end"] < target_start or
+                    predecessor["host_addr"] + predecessor_size != host_addr):
+                    predecessor = None
+
+            if (predecessor is None):
+                # isolated mapping, add it to the list
+                self.guest_phys_blocks.append({"target_start": target_start,
+                                               "target_end"  : target_end,
+                                               "host_addr"   : host_addr})
+                message = "added"
+            else:
+                # expand predecessor until @target_end; predecessor's
+                # start doesn't change
+                predecessor["target_end"] = target_end
+                message = "joined"
+
+            print ("%016x %016x %016x %-7s %5u" %
+                   (target_start, target_end, host_addr.cast(self.uintptr_t),
+                    message, len(self.guest_phys_blocks)))
+
+    def cpu_get_dump_info(self):
+        # We can't synchronize the registers with KVM post-mortem, and
+        # the bits in (first_x86_cpu->env.hflags) seem to be stale; they
+        # may not reflect long mode for example. Hence just assume the
+        # most common values. This also means that instruction pointer
+        # etc. will be bogus in the dump, but at least the RAM contents
+        # should be valid.
+        self.dump_info = {"d_machine": self.EM_X86_64,
+                          "d_endian" : self.ELFDATA2LSB,
+                          "d_class"  : self.ELFCLASS64}
+
+    def encode_elf64_ehdr_le(self):
+        return self.elf64_ehdr_le.pack(
+                                 self.ELFMAG,                 # e_ident/magic
+                                 self.dump_info["d_class"],   # e_ident/class
+                                 self.dump_info["d_endian"],  # e_ident/data
+                                 self.EV_CURRENT,             # e_ident/version
+                                 0,                           # e_ident/osabi
+                                 "",                          # e_ident/pad
+                                 self.ET_CORE,                # e_type
+                                 self.dump_info["d_machine"], # e_machine
+                                 self.EV_CURRENT,             # e_version
+                                 0,                           # e_entry
+                                 self.elf64_ehdr_le.size,     # e_phoff
+                                 0,                           # e_shoff
+                                 0,                           # e_flags
+                                 self.elf64_ehdr_le.size,     # e_ehsize
+                                 self.elf64_phdr_le.size,     # e_phentsize
+                                 self.phdr_num,               # e_phnum
+                                 0,                           # e_shentsize
+                                 0,                           # e_shnum
+                                 0                            # e_shstrndx
+                                )
+
+    def encode_elf64_note_le(self):
+        return self.elf64_phdr_le.pack(self.PT_NOTE,         # p_type
+                                       0,                    # p_flags
+                                       (self.memory_offset -
+                                        len(self.note)),     # p_offset
+                                       0,                    # p_vaddr
+                                       0,                    # p_paddr
+                                       len(self.note),       # p_filesz
+                                       len(self.note),       # p_memsz
+                                       0                     # p_align
+                                      )
+
+    def encode_elf64_load_le(self, offset, start_hwaddr, range_size):
+        return self.elf64_phdr_le.pack(self.PT_LOAD, # p_type
+                                       0,            # p_flags
+                                       offset,       # p_offset
+                                       0,            # p_vaddr
+                                       start_hwaddr, # p_paddr
+                                       range_size,   # p_filesz
+                                       range_size,   # p_memsz
+                                       0             # p_align
+                                      )
+
+    def note_init(self, name, desc, type):
+        # name must include a trailing NUL
+        namesz = (len(name) + 1 + 3) / 4 * 4
+        descsz = (len(desc)     + 3) / 4 * 4
+        fmt = ("<"   # little endian
+               "I"   # n_namesz
+               "I"   # n_descsz
+               "I"   # n_type
+               "%us" # name
+               "%us" # desc
+               % (namesz, descsz))
+        self.note = struct.pack(fmt,
+                                len(name) + 1, len(desc), type, name, desc)
+
+    def dump_init(self):
+        self.guest_phys_blocks_init()
+        self.guest_phys_blocks_append()
+        self.cpu_get_dump_info()
+        # we have no way to retrieve the VCPU status from KVM
+        # post-mortem
+        self.note_init("NONE", "EMPTY", 0)
+
+        # Account for PT_NOTE.
+        self.phdr_num = 1
+
+        # We should never reach PN_XNUM for paging=false dumps: there's
+        # just a handful of discontiguous ranges after merging.
+        self.phdr_num += len(self.guest_phys_blocks)
+        assert (self.phdr_num < self.PN_XNUM)
+
+        # Calculate the ELF file offset where the memory dump commences:
+        #
+        #   ELF header
+        #   PT_NOTE
+        #   PT_LOAD: 1
+        #   PT_LOAD: 2
+        #   ...
+        #   PT_LOAD: len(self.guest_phys_blocks)
+        #   ELF note
+        #   memory dump
+        self.memory_offset = (self.elf64_ehdr_le.size +
+                              self.elf64_phdr_le.size * self.phdr_num +
+                              len(self.note))
+
+    def dump_begin(self, vmcore):
+        vmcore.write(self.encode_elf64_ehdr_le())
+        vmcore.write(self.encode_elf64_note_le())
+        running = self.memory_offset
+        for block in self.guest_phys_blocks:
+            range_size = block["target_end"] - block["target_start"]
+            vmcore.write(self.encode_elf64_load_le(running,
+                                                   block["target_start"],
+                                                   range_size))
+            running += range_size
+        vmcore.write(self.note)
+
+    def dump_iterate(self, vmcore):
+        qemu_core = gdb.inferiors()[0]
+        for block in self.guest_phys_blocks:
+            cur  = block["host_addr"]
+            left = block["target_end"] - block["target_start"]
+            print ("dumping range at %016x for length %016x" %
+                   (cur.cast(self.uintptr_t), left))
+            while (left > 0):
+                chunk_size = min(self.TARGET_PAGE_SIZE, left)
+                chunk = qemu_core.read_memory(cur, chunk_size)
+                vmcore.write(chunk)
+                cur  += chunk_size
+                left -= chunk_size
+
+    def create_vmcore(self, filename):
+        vmcore = open(filename, "wb")
+        self.dump_begin(vmcore)
+        self.dump_iterate(vmcore)
+        vmcore.close()
+
+    def invoke(self, args, from_tty):
+        # Unwittingly pressing the Enter key after the command should
+        # not dump the same multi-gig coredump to the same file.
+        self.dont_repeat()
+
+        argv = gdb.string_to_argv(args)
+        if (len(argv) != 1):
+            raise gdb.GdbError("usage: dump-guest-memory FILE")
+
+        self.dump_init()
+        self.create_vmcore(argv[0])
+
+DumpGuestMemory()
--
1.8.3.1
SOURCES/kvm-Remove-redhat-extensions-from-qmp-events.txt.patch
New file
@@ -0,0 +1,64 @@
From c7a7d2970163c29da5445df54b0fabe28021b275 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 27 May 2015 14:50:33 +0200
Subject: [PATCH 7/8] Remove redhat extensions from qmp-events.txt
Message-id: <021c5d770a75ff1569b7a43a9a08553c9814214c.1432733950.git.mrezanin@redhat.com>
Patchwork-id: 65136
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/2] Remove redhat extensions from qmp-events.txt
Bugzilla: 1222833
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
From: Miroslav Rezanina <mrezanin@redhat.com>
We document __com.redhat_reason and __com.redhat_debug_info event members
in qmp-events. We describe them as RHEL 7 extension. This is true for
qemu-kvm pacakge only, qemu-kvm-rhev uses upstream solution.
Remove this fields from documentation so users do not expect them so they
avoid issues on update to different version of qemu-kvm.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 QMP/qmp-events.txt | 17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index ec4e4b9..7d16a6d 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -146,28 +146,13 @@ Data:
     "ignore": error has been ignored, the job may fail later
     "report": error will be reported and the job canceled
     "stop": error caused job to be paused
-- "__com.redhat_reason": error reason, this is a RHEL7 extension, it's one of
-  the following (json-string):
-    "eio": errno EIO
-    "eperm": errno EPERM
-    "enospc": errno ENOSPC
-    "eother": any other errno (other than EIO, EPERM, ENOSPC)
-- "__com.redhat_debug_info": RHEL7 extension containing debug information for
-                             humans, applications should NOT read any
-                             information from this member (json-object):
-    - "errno": errno value (json-int)
-    - "message": error message returned by strerror() (json-string)
 Example:
 { "event": "BLOCK_JOB_ERROR",
     "data": { "device": "ide0-hd1",
               "operation": "write",
-              "action": "stop",
-              "__com.redhat_reason": "enospc",
-              "__com.redhat_debug_info": {
-                  "message": "No space left on device",
-                  "errno": 28 } }
+              "action": "stop" },
     "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
 BLOCK_JOB_READY
--
1.8.3.1
SOURCES/kvm-Restore-atapi_dma-flag-across-migration.patch
New file
@@ -0,0 +1,47 @@
From 26631da9bba6bcf000b4a87715cb3e8364afc373 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 10 Feb 2015 11:45:35 +0100
Subject: [PATCH 09/16] Restore atapi_dma flag across migration
Message-id: <1423568736-19538-2-git-send-email-dgilbert@redhat.com>
Patchwork-id: 63778
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/2] Restore atapi_dma flag across migration
Bugzilla: 892258
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: John Snow <jsnow@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
If a migration happens just after the guest has kicked
off an ATAPI command and kicked off DMA, we lose the atapi_dma
flag, and the destination tries to complete the command as PIO
rather than DMA.  This upsets Linux; modern libata based kernels
stumble and recover OK, older kernels end up passing bad data
to userspace.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 819fa276311ce328a8e38ad9306c1093961b3f4b)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/ide/core.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 24a1708..9a22425 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2283,6 +2283,7 @@ static int ide_drive_pio_post_load(void *opaque, int version_id)
     s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
     s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
     s->data_end = s->data_ptr + s->cur_io_buffer_len;
+    s->atapi_dma = s->feature & 1; /* as per cmd_packet */
     return 0;
 }
--
1.8.3.1
SOURCES/kvm-ahci.c-mask-unused-flags-when-reading-size-PRDT-DBC.patch
New file
@@ -0,0 +1,92 @@
From e4edeb73e3b9b1ba4efbf18ddb687fb210fd57f8 Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Fri, 26 Jun 2015 21:52:46 +0200
Subject: [PATCH 1/2] ahci.c: mask unused flags when reading size PRDT DBC
Message-id: <1435355567-29641-2-git-send-email-jsnow@redhat.com>
Patchwork-id: 66535
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/2] ahci.c: mask unused flags when reading size PRDT DBC
Bugzilla: 1205100
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Reza Jelveh <reza.jelveh@tuhh.de>
The data byte count(DBC) read from the description information is defined for
bits 21:00. Bits 30:22 are reserved and bit 31 is the Interrupt on Completion
(I) flag.
Completion interrupts are triggered after every transaction instead of on
I-flag in QEMU. tbl_entry_size is a signed integer and improperly reading the
DBC leads to a negative offset that causes sglist allocation to fail.
Signed-off-by: Reza Jelveh <reza.jelveh@tuhh.de>
Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit d02f8adc6d2a178bcbf77d0413f9a96fdbed53f0)
Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/ide/ahci.c | 11 ++++++++---
 hw/ide/ahci.h |  2 ++
 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 011e796..7f3927a 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -635,6 +635,11 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
     }
 }
+static int prdt_tbl_entry_size(const AHCI_SG *tbl)
+{
+    return (le32_to_cpu(tbl->flags_size) & AHCI_PRDT_SIZE_MASK) + 1;
+}
+
 static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
 {
     AHCICmdHdr *cmd = ad->cur_cmd;
@@ -675,7 +680,7 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
         sum = 0;
         for (i = 0; i < sglist_alloc_hint; i++) {
             /* flags_size is zero-based */
-            tbl_entry_size = (le32_to_cpu(tbl[i].flags_size) + 1);
+            tbl_entry_size = prdt_tbl_entry_size(&tbl[i]);
             if (offset <= (sum + tbl_entry_size)) {
                 off_idx = i;
                 off_pos = offset - sum;
@@ -693,12 +698,12 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
         qemu_sglist_init(sglist, (sglist_alloc_hint - off_idx), ad->hba->dma);
         qemu_sglist_add(sglist, le64_to_cpu(tbl[off_idx].addr + off_pos),
-                        le32_to_cpu(tbl[off_idx].flags_size) + 1 - off_pos);
+                        prdt_tbl_entry_size(&tbl[off_idx]) - off_pos);
         for (i = off_idx + 1; i < sglist_alloc_hint; i++) {
             /* flags_size is zero-based */
             qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
-                            le32_to_cpu(tbl[i].flags_size) + 1);
+                            prdt_tbl_entry_size(&tbl[i]));
         }
     }
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 85f37fe..47c0961 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -201,6 +201,8 @@
 #define AHCI_COMMAND_TABLE_ACMD            0x40
+#define AHCI_PRDT_SIZE_MASK                0x3fffff
+
 #define IDE_FEATURE_DMA                    1
 #define READ_FPDMA_QUEUED                  0x60
--
1.8.3.1
SOURCES/kvm-always-update-the-MPX-model-specific-register.patch
New file
@@ -0,0 +1,58 @@
From 7ed89963702e6c53c20864b564a5b43712a38ccd Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com>
Date: Thu, 25 Jun 2015 19:31:24 +0200
Subject: [PATCH 04/10] kvm: always update the MPX model specific register
Message-id: <1435260689-9556-4-git-send-email-ehabkost@redhat.com>
Patchwork-id: 66501
O-Subject: [RHEL-7.2 qemu-kvm PATCH 3/8] kvm: always update the MPX model specific register
Bugzilla: 1233350
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: Bandan Das <bsd@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
From: Paolo Bonzini <pbonzini@redhat.com>
The original patch from Liu Jinsong restricted them to reset or full
state updates, but that's unnecessary (and wrong) since the BNDCFGS
MSR has no side effects.
Cc: Liu Jinsong <jinsong.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 439d19f2922ac409ee224bc1e5522cee7009d829)
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
    target-i386/kvm.c
---
 target-i386/kvm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 6d9aa63..bbbbac0 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1155,6 +1155,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
         kvm_msr_entry_set(&msrs[n++], MSR_IA32_MISC_ENABLE,
                           env->msr_ia32_misc_enable);
     }
+    if (has_msr_bndcfgs) {
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs);
+    }
 #ifdef TARGET_X86_64
     if (lm_capable_kernel) {
         kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
@@ -1266,9 +1269,6 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
                                   MSR_MTRRphysMask(i), env->mtrr_var[i].mask);
             }
         }
-        if (has_msr_bndcfgs) {
-            kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs);
-        }
     }
     if (env->mcg_cap) {
         int i;
--
1.8.3.1
SOURCES/kvm-atapi-migration-Throw-recoverable-error-to-avoid-rec.patch
New file
@@ -0,0 +1,118 @@
From e44bfb41173183a85bb6fa94a6f48486ac4ab0a2 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 10 Feb 2015 11:45:36 +0100
Subject: [PATCH 10/16] atapi migration: Throw recoverable error to avoid
 recovery
Message-id: <1423568736-19538-3-git-send-email-dgilbert@redhat.com>
Patchwork-id: 63779
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/2] atapi migration: Throw recoverable error to avoid recovery
Bugzilla: 892258
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: John Snow <jsnow@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
(With the previous atapi_dma flag recovery)
If migration happens between the ATAPI command being written and the
bmdma being started, the DMA is dropped.  Eventually the guest times
out and recovers, but that can take many seconds.
(This is rare, on a pingpong reading the CD continuously I hit
this about ~1/30-1/50 migrates)
I don't think we've got enough state to be able to recover safely
at this point, so I throw a 'medium error, no seek complete'
that I'm assuming guests will try and recover from an apparently
dirty CD.
OK, it's a hack, the real solution is probably to push a lot of
ATAPI state into the migration stream, but this is a fix that
works with no stream changes. Tested only on Linux (both RHEL5
(pre-libata) and RHEL7).
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit a71754e5b03fd3b8b8c6d3bc2a39f75bead729de)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/ide/atapi.c    | 17 +++++++++++++++++
 hw/ide/internal.h |  2 ++
 hw/ide/pci.c      | 11 +++++++++++
 3 files changed, 30 insertions(+)
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 05e60b1..46a2c26 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -393,6 +393,23 @@ static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
     }
 }
+
+/* Called by *_restart_bh when the transfer function points
+ * to ide_atapi_cmd
+ */
+void ide_atapi_dma_restart(IDEState *s)
+{
+    /*
+     * I'm not sure we have enough stored to restart the command
+     * safely, so give the guest an error it should recover from.
+     * I'm assuming most guests will try to recover from something
+     * listed as a medium error on a CD; it seems to work on Linux.
+     * This would be more of a problem if we did any other type of
+     * DMA operation.
+     */
+    ide_atapi_cmd_error(s, MEDIUM_ERROR, ASC_NO_SEEK_COMPLETE);
+}
+
 static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
                                             uint16_t profile)
 {
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 048a052..0a2d6bc 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -289,6 +289,7 @@ typedef struct IDEDMAOps IDEDMAOps;
 #define ATAPI_INT_REASON_TAG            0xf8
 /* same constants as bochs */
+#define ASC_NO_SEEK_COMPLETE                 0x02
 #define ASC_ILLEGAL_OPCODE                   0x20
 #define ASC_LOGICAL_BLOCK_OOR                0x21
 #define ASC_INV_FIELD_IN_CMD_PACKET          0x24
@@ -536,6 +537,7 @@ void ide_dma_error(IDEState *s);
 void ide_atapi_cmd_ok(IDEState *s);
 void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc);
+void ide_atapi_dma_restart(IDEState *s);
 void ide_atapi_io_error(IDEState *s, int ret);
 void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val);
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 635a364..cf7acb0 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -220,6 +220,17 @@ static void bmdma_restart_bh(void *opaque)
         }
     } else if (error_status & BM_STATUS_RETRY_FLUSH) {
         ide_flush_cache(bmdma_active_if(bm));
+    } else {
+        IDEState *s = bmdma_active_if(bm);
+
+        /*
+         * We've not got any bits to tell us about ATAPI - but
+         * we do have the end_transfer_func that tells us what
+         * we're trying to do.
+         */
+        if (s->end_transfer_func == ide_atapi_cmd) {
+            ide_atapi_dma_restart(s);
+        }
     }
 }
--
1.8.3.1
SOURCES/kvm-atomics-add-explicit-compiler-fence-in-__atomic-memo.patch
@@ -1,4 +1,4 @@
From 0f918da30dbb71e68e7fad4a2da8983b25536233 Mon Sep 17 00:00:00 2001
From d37475eb567b61ce6a18f9fcbf35eb929be8d99f Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 19 Jun 2015 10:45:29 +0200
Subject: [PATCH] atomics: add explicit compiler fence in __atomic memory
@@ -7,11 +7,15 @@
Message-id: <1434710730-26183-1-git-send-email-pbonzini@redhat.com>
Patchwork-id: 66333
O-Subject: [RHEL7.2/7.1.z qemu-kvm PATCH] atomics: add explicit compiler fence in __atomic memory barriers
Bugzilla: 1233643
Bugzilla: 1142857
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Bugzilla: 1142857 (aka 8*10^6/7)
Brew build: 9393725
__atomic_thread_fence does not include a compiler barrier; in the
C++11 memory model, fences take effect in combination with other
atomic operations.  GCC implements this by making __atomic_load and
SOURCES/kvm-block-Add-Error-argument-to-bdrv_refresh_limits.patch
New file
@@ -0,0 +1,307 @@
From 1aac494dfcc4f96e04f3ad8bc14db8f17c48626f Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Tue, 17 Mar 2015 13:02:48 +0100
Subject: [PATCH 13/16] block: Add Error argument to bdrv_refresh_limits()
Message-id: <1424365599-9801-2-git-send-email-stefanha@redhat.com>
Patchwork-id: 63914
O-Subject: [RHEL-7.1 qemu-kvm PATCH 1/2] block: Add Error argument to bdrv_refresh_limits()
Bugzilla: 1184363
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: John Snow <jsnow@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 3baca891391afba154e250f5a108c6bab6c92cf9)
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Conflicts:
        block.c
bdrv_set_backing_hd() does not exist downstream so there are extra
bdrv_refresh_limits() occurrences downstream.  They pass a NULL errp
argument as bdrv_set_backing_hd() would.
        block/iscsi.c
Context conflict, easy to resolve.
        block/raw_bsd.c
Does not exist downstream, apply change to block/raw.c instead.
---
 block.c                   | 35 ++++++++++++++++++++++++-----------
 block/iscsi.c             |  4 +---
 block/qcow2.c             |  4 +---
 block/qed.c               |  4 +---
 block/raw-posix.c         |  4 +---
 block/raw.c               |  3 +--
 block/stream.c            |  2 +-
 block/vmdk.c              |  4 +---
 include/block/block.h     |  2 +-
 include/block/block_int.h |  2 +-
 10 files changed, 33 insertions(+), 31 deletions(-)
diff --git a/block.c b/block.c
index 21418a6..89ab829 100644
--- a/block.c
+++ b/block.c
@@ -462,19 +462,24 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
     return ret;
 }
-int bdrv_refresh_limits(BlockDriverState *bs)
+void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BlockDriver *drv = bs->drv;
+    Error *local_err = NULL;
     memset(&bs->bl, 0, sizeof(bs->bl));
     if (!drv) {
-        return 0;
+        return;
     }
     /* Take some limits from the children as a default */
     if (bs->file) {
-        bdrv_refresh_limits(bs->file);
+        bdrv_refresh_limits(bs->file, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
         bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
         bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
     } else {
@@ -482,7 +487,11 @@ int bdrv_refresh_limits(BlockDriverState *bs)
     }
     if (bs->backing_hd) {
-        bdrv_refresh_limits(bs->backing_hd);
+        bdrv_refresh_limits(bs->backing_hd, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
         bs->bl.opt_transfer_length =
             MAX(bs->bl.opt_transfer_length,
                 bs->backing_hd->bl.opt_transfer_length);
@@ -493,10 +502,8 @@ int bdrv_refresh_limits(BlockDriverState *bs)
     /* Then let the driver override it */
     if (drv->bdrv_refresh_limits) {
-        return drv->bdrv_refresh_limits(bs);
+        drv->bdrv_refresh_limits(bs, errp);
     }
-
-    return 0;
 }
 /*
@@ -856,7 +863,13 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
         goto free_and_fail;
     }
-    bdrv_refresh_limits(bs);
+    bdrv_refresh_limits(bs, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        ret = -EINVAL;
+        goto free_and_fail;
+    }
+
     assert(bdrv_opt_mem_align(bs) != 0);
     assert((bs->request_alignment != 0) || bs->sg);
@@ -1048,7 +1061,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
     }
     /* Recalculate the BlockLimits with the backing file */
-    bdrv_refresh_limits(bs);
+    bdrv_refresh_limits(bs, NULL);
     return 0;
 }
@@ -1483,7 +1496,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
                                               BDRV_O_CACHE_WB);
     reopen_state->bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);
-    bdrv_refresh_limits(reopen_state->bs);
+    bdrv_refresh_limits(reopen_state->bs, NULL);
 }
 /*
@@ -2398,7 +2411,7 @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
     }
     new_top_bs->backing_hd = base_bs;
-    bdrv_refresh_limits(new_top_bs);
+    bdrv_refresh_limits(new_top_bs, NULL);
     QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) {
         /* so that bdrv_close() does not recursively close the chain */
diff --git a/block/iscsi.c b/block/iscsi.c
index 3d61dd7..2a4ab22 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1550,7 +1550,7 @@ static void iscsi_close(BlockDriverState *bs)
     memset(iscsilun, 0, sizeof(IscsiLun));
 }
-static int iscsi_refresh_limits(BlockDriverState *bs)
+static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     IscsiLun *iscsilun = bs->opaque;
@@ -1576,8 +1576,6 @@ static int iscsi_refresh_limits(BlockDriverState *bs)
         bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len,
                                                      iscsilun);
     }
-
-    return 0;
 }
 /* We have nothing to do for iSCSI reopen, stub just returns
diff --git a/block/qcow2.c b/block/qcow2.c
index 43e54d6..005d513 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -848,13 +848,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
     return ret;
 }
-static int qcow2_refresh_limits(BlockDriverState *bs)
+static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVQcowState *s = bs->opaque;
     bs->bl.write_zeroes_alignment = s->cluster_sectors;
-
-    return 0;
 }
 static int qcow2_set_key(BlockDriverState *bs, const char *key)
diff --git a/block/qed.c b/block/qed.c
index d1de0a2..5793fca 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -507,13 +507,11 @@ out:
     return ret;
 }
-static int bdrv_qed_refresh_limits(BlockDriverState *bs)
+static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVQEDState *s = bs->opaque;
     bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS;
-
-    return 0;
 }
 /* We have nothing to do for QED reopen, stubs just return
diff --git a/block/raw-posix.c b/block/raw-posix.c
index af526ca..46b941b 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -588,14 +588,12 @@ static void raw_reopen_abort(BDRVReopenState *state)
     state->opaque = NULL;
 }
-static int raw_refresh_limits(BlockDriverState *bs)
+static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVRawState *s = bs->opaque;
     raw_probe_alignment(bs, s->fd, errp);
     bs->bl.opt_mem_alignment = s->buf_align;
-
-    return 0;
 }
 static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb)
diff --git a/block/raw.c b/block/raw.c
index eeadba5..a750359 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -58,10 +58,9 @@ static int64_t raw_getlength(BlockDriverState *bs)
     return bdrv_getlength(bs->file);
 }
-static int raw_refresh_limits(BlockDriverState *bs)
+static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     bs->bl = bs->file->bl;
-    return 0;
 }
 static int raw_truncate(BlockDriverState *bs, int64_t offset)
diff --git a/block/stream.c b/block/stream.c
index 367120d..4e4436c 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -72,7 +72,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
     }
     top->backing_hd = base;
-    bdrv_refresh_limits(top);
+    bdrv_refresh_limits(top, NULL);
 }
 static void coroutine_fn stream_run(void *opaque)
diff --git a/block/vmdk.c b/block/vmdk.c
index cfcaa84..24e9458 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -954,7 +954,7 @@ fail:
 }
-static int vmdk_refresh_limits(BlockDriverState *bs)
+static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVVmdkState *s = bs->opaque;
     int i;
@@ -966,8 +966,6 @@ static int vmdk_refresh_limits(BlockDriverState *bs)
                     s->extents[i].cluster_sectors);
         }
     }
-
-    return 0;
 }
 /**
diff --git a/include/block/block.h b/include/block/block.h
index c79a1e1..3170cbc 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -254,7 +254,7 @@ int64_t bdrv_nb_sectors(BlockDriverState *bs);
 int64_t bdrv_getlength(BlockDriverState *bs);
 int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
-int bdrv_refresh_limits(BlockDriverState *bs);
+void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
 int bdrv_commit(BlockDriverState *bs);
 int bdrv_commit_all(void);
 int bdrv_change_backing_file(BlockDriverState *bs,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index e6874b4..3f86649 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -213,7 +213,7 @@ struct BlockDriver {
     int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
     bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
-    int (*bdrv_refresh_limits)(BlockDriverState *bs);
+    void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
     /*
      * Returns 1 if newly created images are guaranteed to contain only
--
1.8.3.1
SOURCES/kvm-block-Add-qemu_-try_-blockalign0.patch
New file
@@ -0,0 +1,81 @@
From ad8bc0d8901415eeea7bb27ef26f197918be0752 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Sat, 13 Jun 2015 16:22:09 +0200
Subject: [PATCH 15/42] block: Add qemu_{,try_}blockalign0()
Message-id: <1434212556-3927-16-git-send-email-mreitz@redhat.com>
Patchwork-id: 66034
O-Subject: [RHEL-7.2 qemu-kvm PATCH 15/42] block: Add qemu_{,try_}blockalign0()
Bugzilla: 1129893
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
BZ: 1129893
These functions call their non-0-counterparts and then fill the
allocated buffer with 0 (if the allocation has been successful).
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9ebd84480583bb6d9a7666c079d99ff3266c423d)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c               | 16 ++++++++++++++++
 include/block/block.h |  2 ++
 2 files changed, 18 insertions(+)
diff --git a/block.c b/block.c
index 1afa544..22ab762 100644
--- a/block.c
+++ b/block.c
@@ -5178,6 +5178,11 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size)
     return qemu_memalign(bdrv_opt_mem_align(bs), size);
 }
+void *qemu_blockalign0(BlockDriverState *bs, size_t size)
+{
+    return memset(qemu_blockalign(bs, size), 0, size);
+}
+
 void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
 {
     size_t align = bdrv_opt_mem_align(bs);
@@ -5191,6 +5196,17 @@ void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
     return qemu_try_memalign(align, size);
 }
+void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
+{
+    void *mem = qemu_try_blockalign(bs, size);
+
+    if (mem) {
+        memset(mem, 0, size);
+    }
+
+    return mem;
+}
+
 /*
  * Check if all memory in this vector is sector aligned.
  */
diff --git a/include/block/block.h b/include/block/block.h
index 7b538b7..8339cac 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -417,7 +417,9 @@ void bdrv_img_create(const char *filename, const char *fmt,
 size_t bdrv_opt_mem_align(BlockDriverState *bs);
 void bdrv_set_guest_block_size(BlockDriverState *bs, int align);
 void *qemu_blockalign(BlockDriverState *bs, size_t size);
+void *qemu_blockalign0(BlockDriverState *bs, size_t size);
 void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
+void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
 bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
 struct HBitmapIter;
--
1.8.3.1
SOURCES/kvm-block-Allow-JSON-filenames.patch
New file
@@ -0,0 +1,89 @@
From c2eb29efe61ffe88d3aff449446a9ac0f0f045a5 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Tue, 2 Jun 2015 09:46:37 +0200
Subject: [PATCH 3/4] block: Allow JSON filenames
Message-id: <1433238397-2500-3-git-send-email-rjones@redhat.com>
Patchwork-id: 65279
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/2] block: Allow JSON filenames
Bugzilla: 1226697
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
From: Max Reitz <mreitz@redhat.com>
If the filename given to bdrv_open() is prefixed with "json:", parse the
rest as a JSON object and merge the result into the options QDict. If
there are conflicts, the options QDict takes precedence.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
diff --git a/block.c b/block.c
index 45543d5..f2caf20 100644
--- a/block.c
+++ b/block.c
@@ -1085,6 +1085,33 @@ static void extract_subqdict(QDict *src, QDict **dst, const char *start)
     }
 }
+static QDict *parse_json_filename(const char *filename, Error **errp)
+{
+    QObject *options_obj;
+    QDict *options;
+    int ret;
+
+    ret = strstart(filename, "json:", &filename);
+    assert(ret);
+
+    options_obj = qobject_from_json(filename);
+    if (!options_obj) {
+        error_setg(errp, "Could not parse the JSON options");
+        return NULL;
+    }
+
+    if (qobject_type(options_obj) != QTYPE_QDICT) {
+        qobject_decref(options_obj);
+        error_setg(errp, "Invalid JSON object given");
+        return NULL;
+    }
+
+    options = qobject_to_qdict(options_obj);
+    qdict_flatten(options);
+
+    return options;
+}
+
 /*
  * Opens a disk image (raw, qcow2, vmdk, ...)
  *
@@ -1109,6 +1136,20 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
         options = qdict_new();
     }
+    if (filename && g_str_has_prefix(filename, "json:")) {
+        QDict *json_options = parse_json_filename(filename, &local_err);
+        if (local_err) {
+            ret = -EINVAL;
+            goto fail;
+        }
+
+        /* Options given in the filename have lower priority than options
+         * specified directly */
+        qdict_join(options, json_options, false);
+        QDECREF(json_options);
+        filename = NULL;
+    }
+
     bs->options = options;
     options = qdict_clone_shallow(options);
--
1.8.3.1
SOURCES/kvm-block-Catch-bs-drv-in-bdrv_check.patch
New file
@@ -0,0 +1,48 @@
From c7d5655eea99e3a62075c5ca067a6d8f670ddf9d Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Sat, 13 Jun 2015 16:22:00 +0200
Subject: [PATCH 06/42] block: Catch !bs->drv in bdrv_check()
Message-id: <1434212556-3927-7-git-send-email-mreitz@redhat.com>
Patchwork-id: 66025
O-Subject: [RHEL-7.2 qemu-kvm PATCH 06/42] block: Catch !bs->drv in bdrv_check()
Bugzilla: 1129893
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
BZ: 1129893
qemu-img check calls bdrv_check() twice if the first run repaired some
inconsistencies. If the first run however again triggered corruption
prevention (on qcow2) due to very bad inconsistencies, bs->drv may be
NULL afterwards. Thus, bdrv_check() should check whether bs->drv is set.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 908bcd540f489f7adf2d804347905b0025d808d3)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/block.c b/block.c
index caea2ea..1afa544 100644
--- a/block.c
+++ b/block.c
@@ -1998,6 +1998,9 @@ bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
  */
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
 {
+    if (bs->drv == NULL) {
+        return -ENOMEDIUM;
+    }
     if (bs->drv->bdrv_check == NULL) {
         return -ENOTSUP;
     }
--
1.8.3.1
SOURCES/kvm-block-Don-t-probe-for-unknown-backing-file-format.patch
New file
@@ -0,0 +1,203 @@
From a0f50f0877463e9370ffa411bd826d7c704ab9fe Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Sat, 13 Jun 2015 16:22:30 +0200
Subject: [PATCH 36/42] block: Don't probe for unknown backing file format
Message-id: <1434212556-3927-37-git-send-email-mreitz@redhat.com>
Patchwork-id: 66055
O-Subject: [RHEL-7.2 qemu-kvm PATCH 36/42] block: Don't probe for unknown backing file format
Bugzilla: 1129893
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Kevin Wolf <kwolf@redhat.com>
BZ: 1129893
If a qcow2 image specifies a backing file format that doesn't correspond
to any format driver that qemu knows, we shouldn't fall back to probing,
but simply error out.
Not looking up the backing file driver in bdrv_open_backing_file(), but
just filling in the "driver" option if it isn't there moves us closer to
the goal of having everything in QDict options and gets us the error
handling of bdrv_open(), which correctly refuses unknown drivers.
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1416935562-7760-4-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit c5f6e493bb5339d244eae5d3f21c5b6d73996739)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
    block.c
    tests/qemu-iotests/114.out
Downstream is missing a check whether the driver specified by the
"driver" option is actually valid (if it is not, it will be probed
anyway); this check is introduced upstream by
17b005f1d422d4581f8ce95b75d603deb081f4f3, but that commit has a couple
of dependencies and relies on a code path that is very different from
downstream (e.g. not bdrv_file_open() anymore). So I just introduced the
check in this patch.
Also, the different code paths upstream and downstream result in the
error message missing the "Could not open backing file:" part, which
means that 114.out has to be fixed up.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c                    | 12 ++++++---
 tests/qemu-iotests/114     | 61 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/114.out | 13 ++++++++++
 tests/qemu-iotests/group   |  1 +
 4 files changed, 83 insertions(+), 4 deletions(-)
 create mode 100755 tests/qemu-iotests/114
 create mode 100644 tests/qemu-iotests/114.out
diff --git a/block.c b/block.c
index fa6e192..e36fa2f 100644
--- a/block.c
+++ b/block.c
@@ -1010,7 +1010,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
 {
     char backing_filename[PATH_MAX];
     int back_flags, ret;
-    BlockDriver *back_drv = NULL;
     Error *local_err = NULL;
     if (bs->backing_hd != NULL) {
@@ -1036,8 +1035,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
     bs->backing_hd = bdrv_new("", &error_abort);
-    if (bs->backing_format[0] != '\0') {
-        back_drv = bdrv_find_format(bs->backing_format);
+    if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
+        qdict_put(options, "driver", qstring_from_str(bs->backing_format));
     }
     /* backing files always opened read-only */
@@ -1046,7 +1045,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
     ret = bdrv_open(bs->backing_hd,
                     *backing_filename ? backing_filename : NULL, options,
-                    back_flags, back_drv, &local_err);
+                    back_flags, NULL, &local_err);
     if (ret < 0) {
         bdrv_unref(bs->backing_hd);
         bs->backing_hd = NULL;
@@ -1244,6 +1243,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
     if (drvname) {
         drv = bdrv_find_format(drvname);
         qdict_del(options, "driver");
+        if (!drv) {
+            error_setg(errp, "Unknown driver '%s'", drvname);
+            ret = -EINVAL;
+            goto unlink_and_fail;
+        }
     }
     if (!drv) {
diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
new file mode 100755
index 0000000..d02e7ff
--- /dev/null
+++ b/tests/qemu-iotests/114
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# Test invalid backing file format in qcow2 images
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+tmp=/tmp/$$
+status=1    # failure is the default!
+
+_cleanup()
+{
+    _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+
+TEST_IMG="$TEST_IMG.base" _make_test_img 64M
+_make_test_img -b "$TEST_IMG.base" 64M
+
+# Set an invalid backing file format
+$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0xE2792ACA "foo"
+_img_info
+
+# Try opening the image. Should fail (and not probe) in the first case, but
+# overriding the backing file format should be possible.
+$QEMU_IO -c "open $TEST_IMG" -c "read 0 4k" 2>&1 | _filter_qemu_io | _filter_testdir
+$QEMU_IO -c "open -o backing.driver=$IMGFMT $TEST_IMG" -c "read 0 4k" | _filter_qemu_io
+
+# success, all done
+echo '*** done'
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
new file mode 100644
index 0000000..de8f529
--- /dev/null
+++ b/tests/qemu-iotests/114.out
@@ -0,0 +1,13 @@
+QA output created by 114
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 64M (67108864 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT.base
+backing file format: foo
+qemu-io: can't open device TEST_DIR/t.qcow2: Unknown driver 'foo'
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 695ab02..5867cf7 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -88,3 +88,4 @@
 105 rw auto quick
 107 rw auto quick
 108 rw auto quick
+114 rw auto quick
--
1.8.3.1
SOURCES/kvm-block-Drop-superfluous-conditionals-around-g_free.patch
New file
@@ -0,0 +1,75 @@
From 348879493233388280a097c75f5a371512d7918b Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Thu, 11 Jun 2015 11:40:23 +0200
Subject: [PATCH 23/30] block: Drop superfluous conditionals around g_free()
Message-id: <1434022828-13037-17-git-send-email-rjones@redhat.com>
Patchwork-id: 65853
O-Subject: [RHEL-7.2 qemu-kvm v3 PATCH 16/21] block: Drop superfluous conditionals around g_free()
Bugzilla: 1226684
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Upstream-status: f7047c2daf760385edf83df10be4259bea190e75
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/curl.c       | 3 +--
 block/iscsi.c      | 4 +---
 hw/block/onenand.c | 4 +---
 3 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/block/curl.c b/block/curl.c
index e48cc87..d95789a 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -614,8 +614,7 @@ static void curl_readv_bh_cb(void *p)
     acb->end = (acb->nb_sectors * SECTOR_SIZE);
     state->buf_off = 0;
-    if (state->orig_buf)
-        g_free(state->orig_buf);
+    g_free(state->orig_buf);
     state->buf_start = start;
     state->buf_len = acb->end + s->readahead_size;
     end = MIN(start + state->buf_len, s->len) - 1;
diff --git a/block/iscsi.c b/block/iscsi.c
index 2a4ab22..92dc1dd 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1516,9 +1516,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
 out:
     qemu_opts_del(opts);
-    if (initiator_name != NULL) {
-        g_free(initiator_name);
-    }
+    g_free(initiator_name);
     if (iscsi_url != NULL) {
         iscsi_destroy_url(iscsi_url);
     }
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index 8b511a7..55768ec 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -329,9 +329,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
                                     dp, 1) < 0;
             }
         }
-        if (dp) {
-            g_free(dp);
-        }
+        g_free(dp);
     }
     return result;
 }
--
1.8.3.1
SOURCES/kvm-block-Fix-NULL-deference-for-unaligned-write-if-qiov.patch
New file
@@ -0,0 +1,174 @@
From 22db646a6d358e08c4c11f12e3dcf96f25525bf8 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famz@redhat.com>
Date: Mon, 25 May 2015 04:45:56 +0200
Subject: [PATCH 4/6] block: Fix NULL deference for unaligned write if qiov is
 NULL
Message-id: <1432529157-20381-3-git-send-email-famz@redhat.com>
Patchwork-id: 65120
O-Subject: [RHEL-7.2 qemu-kvm PATCH v2 2/3] block: Fix NULL deference for unaligned write if qiov is NULL
Bugzilla: 1200295
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
For zero write, callers pass in NULL qiov (qemu-io "write -z" or
scsi-disk "write same").
Commit fc3959e466 fixed bdrv_co_write_zeroes which is the common case
for this bug, but it still exists in bdrv_aio_write_zeroes. A simpler
fix would be in bdrv_co_do_pwritev which is the NULL dereference point
and covers both cases.
So don't access it in bdrv_co_do_pwritev in this case, use three aligned
writes.
[Initialize ret to 0 in bdrv_co_do_zero_pwritev() to avoid uninitialized
variable warning with gcc 4.9.2.
--Stefan]
Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1431522721-3266-3-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 9eeb6dd1b27bd57eb4e3869290e87feac8e8b226)
We don't have block/io.c in downstream, applied the change to
block.c
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index 89ab829..45543d5 100644
--- a/block.c
+++ b/block.c
@@ -3069,6 +3069,94 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
     return ret;
 }
+static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
+                                                int64_t offset,
+                                                unsigned int bytes,
+                                                BdrvRequestFlags flags,
+                                                BdrvTrackedRequest *req)
+{
+    uint8_t *buf = NULL;
+    QEMUIOVector local_qiov;
+    struct iovec iov;
+    uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
+    unsigned int head_padding_bytes, tail_padding_bytes;
+    int ret = 0;
+
+    head_padding_bytes = offset & (align - 1);
+    tail_padding_bytes = align - ((offset + bytes) & (align - 1));
+
+
+    assert(flags & BDRV_REQ_ZERO_WRITE);
+    if (head_padding_bytes || tail_padding_bytes) {
+        buf = qemu_blockalign(bs, align);
+        iov = (struct iovec) {
+            .iov_base   = buf,
+            .iov_len    = align,
+        };
+        qemu_iovec_init_external(&local_qiov, &iov, 1);
+    }
+    if (head_padding_bytes) {
+        uint64_t zero_bytes = MIN(bytes, align - head_padding_bytes);
+
+        /* RMW the unaligned part before head. */
+        mark_request_serialising(req, align);
+        wait_serialising_requests(req);
+        BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_HEAD);
+        ret = bdrv_aligned_preadv(bs, req, offset & ~(align - 1), align,
+                                  align, &local_qiov, 0);
+        if (ret < 0) {
+            goto fail;
+        }
+        BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
+
+        memset(buf + head_padding_bytes, 0, zero_bytes);
+        ret = bdrv_aligned_pwritev(bs, req, offset & ~(align - 1), align,
+                                   &local_qiov,
+                                   flags & ~BDRV_REQ_ZERO_WRITE);
+        if (ret < 0) {
+            goto fail;
+        }
+        offset += zero_bytes;
+        bytes -= zero_bytes;
+    }
+
+    assert(!bytes || (offset & (align - 1)) == 0);
+    if (bytes >= align) {
+        /* Write the aligned part in the middle. */
+        uint64_t aligned_bytes = bytes & ~(align - 1);
+        ret = bdrv_aligned_pwritev(bs, req, offset, aligned_bytes,
+                                   NULL, flags);
+        if (ret < 0) {
+            goto fail;
+        }
+        bytes -= aligned_bytes;
+        offset += aligned_bytes;
+    }
+
+    assert(!bytes || (offset & (align - 1)) == 0);
+    if (bytes) {
+        assert(align == tail_padding_bytes + bytes);
+        /* RMW the unaligned part after tail. */
+        mark_request_serialising(req, align);
+        wait_serialising_requests(req);
+        BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_TAIL);
+        ret = bdrv_aligned_preadv(bs, req, offset, align,
+                                  align, &local_qiov, 0);
+        if (ret < 0) {
+            goto fail;
+        }
+        BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
+
+        memset(buf, 0, bytes);
+        ret = bdrv_aligned_pwritev(bs, req, offset, align,
+                                   &local_qiov, flags & ~BDRV_REQ_ZERO_WRITE);
+    }
+fail:
+    qemu_vfree(buf);
+    return ret;
+
+}
+
 /*
  * Handle a write request in coroutine context
  */
@@ -3108,6 +3196,11 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
      */
     tracked_request_begin(&req, bs, offset, bytes, true);
+    if (!qiov) {
+        ret = bdrv_co_do_zero_pwritev(bs, offset, bytes, flags, &req);
+        goto out;
+    }
+
     if (offset & (align - 1)) {
         QEMUIOVector head_qiov;
         struct iovec head_iov;
@@ -3181,14 +3274,14 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
                                flags);
 fail:
-    tracked_request_end(&req);
     if (use_local_qiov) {
         qemu_iovec_destroy(&local_qiov);
     }
     qemu_vfree(head_buf);
     qemu_vfree(tail_buf);
-
+out:
+    tracked_request_end(&req);
     return ret;
 }
--
1.8.3.1
SOURCES/kvm-block-Introduce-qemu_try_blockalign.patch
New file
@@ -0,0 +1,156 @@
From 90fad0c40a1947e229fdf82a30219e33a3e1dad8 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Sat, 13 Jun 2015 16:21:57 +0200
Subject: [PATCH 03/42] block: Introduce qemu_try_blockalign()
Message-id: <1434212556-3927-4-git-send-email-mreitz@redhat.com>
Patchwork-id: 66022
O-Subject: [RHEL-7.2 qemu-kvm PATCH 03/42] block: Introduce qemu_try_blockalign()
Bugzilla: 1129893
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Kevin Wolf <kwolf@redhat.com>
BZ: 1129893
This function returns NULL instead of aborting when an allocation fails.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
(cherry picked from commit 7d2a35cc921ea4832083a7e8598461868bb538ce)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c               | 13 +++++++++++++
 include/block/block.h |  1 +
 include/qemu/osdep.h  |  1 +
 util/oslib-posix.c    | 16 ++++++++++------
 util/oslib-win32.c    |  9 +++++++--
 5 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/block.c b/block.c
index f2caf20..caea2ea 100644
--- a/block.c
+++ b/block.c
@@ -5175,6 +5175,19 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size)
     return qemu_memalign(bdrv_opt_mem_align(bs), size);
 }
+void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
+{
+    size_t align = bdrv_opt_mem_align(bs);
+
+    /* Ensure that NULL is never returned on success */
+    assert(align > 0);
+    if (size == 0) {
+        size = align;
+    }
+
+    return qemu_try_memalign(align, size);
+}
+
 /*
  * Check if all memory in this vector is sector aligned.
  */
diff --git a/include/block/block.h b/include/block/block.h
index 3170cbc..7b538b7 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -417,6 +417,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
 size_t bdrv_opt_mem_align(BlockDriverState *bs);
 void bdrv_set_guest_block_size(BlockDriverState *bs, int align);
 void *qemu_blockalign(BlockDriverState *bs, size_t size);
+void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
 bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
 struct HBitmapIter;
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 7a5ae28..8984da0 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -95,6 +95,7 @@ typedef signed int              int_fast16_t;
 #define qemu_printf printf
 int qemu_daemon(int nochdir, int noclose);
+void *qemu_try_memalign(size_t alignment, size_t size);
 void *qemu_memalign(size_t alignment, size_t size);
 void *qemu_anon_ram_alloc(size_t size);
 void qemu_vfree(void *ptr);
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index fef840a..f0fb297 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -83,7 +83,7 @@ void *qemu_oom_check(void *ptr)
     return ptr;
 }
-void *qemu_memalign(size_t alignment, size_t size)
+void *qemu_try_memalign(size_t alignment, size_t size)
 {
     void *ptr;
@@ -95,19 +95,23 @@ void *qemu_memalign(size_t alignment, size_t size)
     int ret;
     ret = posix_memalign(&ptr, alignment, size);
     if (ret != 0) {
-        fprintf(stderr, "Failed to allocate %zu B: %s\n",
-                size, strerror(ret));
-        abort();
+        errno = ret;
+        ptr = NULL;
     }
 #elif defined(CONFIG_BSD)
-    ptr = qemu_oom_check(valloc(size));
+    ptr = valloc(size);
 #else
-    ptr = qemu_oom_check(memalign(alignment, size));
+    ptr = memalign(alignment, size);
 #endif
     trace_qemu_memalign(alignment, size, ptr);
     return ptr;
 }
+void *qemu_memalign(size_t alignment, size_t size)
+{
+    return qemu_oom_check(qemu_try_memalign(alignment, size));
+}
+
 /* alloc shared memory pages */
 void *qemu_anon_ram_alloc(size_t size)
 {
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 332e743..0fb78ef 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -46,18 +46,23 @@ void *qemu_oom_check(void *ptr)
     return ptr;
 }
-void *qemu_memalign(size_t alignment, size_t size)
+void *qemu_try_memalign(size_t alignment, size_t size)
 {
     void *ptr;
     if (!size) {
         abort();
     }
-    ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
+    ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
     trace_qemu_memalign(alignment, size, ptr);
     return ptr;
 }
+void *qemu_memalign(size_t alignment, size_t size)
+{
+    return qemu_oom_check(qemu_try_memalign(alignment, size));
+}
+
 void *qemu_anon_ram_alloc(size_t size)
 {
     void *ptr;
--
1.8.3.1
SOURCES/kvm-block-Print-its-file-name-if-backing-file-opening-fa.patch
New file
@@ -0,0 +1,172 @@
From 82023923707c148ddd91eb3ac18fc9befc4288d5 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Wed, 22 Jul 2015 16:24:55 +0200
Subject: [PATCH 3/5] block: Print its file name if backing file opening failed
Message-id: <1437582297-9244-2-git-send-email-mreitz@redhat.com>
Patchwork-id: 67106
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/3] block: Print its file name if backing file opening failed
Bugzilla: 1238639
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
From: Fam Zheng <famz@redhat.com>
If backing file doesn't exist, the error message is confusing and
misleading:
    $ qemu /tmp/a.qcow2
    qemu: could not open disk image /tmp/a.qcow2: Could not open file: No
    such file or directory
But...
    $ ls /tmp/a.qcow2
    /tmp/a.qcow2
    $ qemu-img info /tmp/a.qcow2
    image: /tmp/a.qcow2
    file format: qcow2
    virtual size: 8.0G (8589934592 bytes)
    disk size: 196K
    cluster_size: 65536
    backing file: /tmp/b.qcow2
Because...
    $ ls /tmp/b.qcow2
    ls: cannot access /tmp/b.qcow2: No such file or directory
This is not intuitive. It's better to have the missing file's name in
the error message. With this patch:
    $ qemu-io -c 'read 0 512' /tmp/a.qcow2
    qemu-io: can't open device /tmp/a.qcow2: Could not open backing
    file: Could not open '/stor/vm/arch.raw': No such file or directory
    no file open, try 'help open'
Which is a little bit better.
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b04b6b6ec3a1e0ba90c2f58617286d9fc35fa372)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
    tests/qemu-iotests/082.out
    tests/qemu-iotests/114.out
When both tests were introduced downstream
(6b1816a687831a1622637ed10605759d9e90aa9c and
a0f50f0877463e9370ffa411bd826d7c704ab9fe, respectively), they were
modified from upstream because this patch had not been backported. These
changes are now reverted.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c                    | 4 +++-
 block/raw-posix.c          | 1 -
 block/raw-win32.c          | 1 -
 tests/qemu-iotests/051.out | 2 +-
 tests/qemu-iotests/069.out | 2 +-
 tests/qemu-iotests/082.out | 4 ++--
 tests/qemu-iotests/114.out | 2 +-
 7 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/block.c b/block.c
index e36fa2f..dedfa52 100644
--- a/block.c
+++ b/block.c
@@ -1050,7 +1050,9 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
         bdrv_unref(bs->backing_hd);
         bs->backing_hd = NULL;
         bs->open_flags |= BDRV_O_NO_BACKING;
-        error_propagate(errp, local_err);
+        error_setg(errp, "Could not open backing file: %s",
+                   error_get_pretty(local_err));
+        error_free(local_err);
         return ret;
     }
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 46b941b..72a9dc0 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -388,7 +388,6 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
         if (ret == -EROFS) {
             ret = -EACCES;
         }
-        error_setg_errno(errp, -ret, "Could not open file");
         goto fail;
     }
     s->fd = fd;
diff --git a/block/raw-win32.c b/block/raw-win32.c
index ac20370..bb6dc6a 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -319,7 +319,6 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
         } else {
             ret = -EINVAL;
         }
-        error_setg_errno(errp, -ret, "Could not open file");
         goto fail;
     }
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 4fca1ca..32c94e5 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -169,6 +169,6 @@ Testing: -drive file=foo:bar
 QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: Unknown protocol
 Testing: -drive file.filename=foo:bar
-QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: Could not open file: No such file or directory
+QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: Could not open 'foo:bar': No such file or directory
 *** done
diff --git a/tests/qemu-iotests/069.out b/tests/qemu-iotests/069.out
index 3648814..b48306d 100644
--- a/tests/qemu-iotests/069.out
+++ b/tests/qemu-iotests/069.out
@@ -4,5 +4,5 @@ QA output created by 069
 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=131072
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file='TEST_DIR/t.IMGFMT.base'
-qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open file: No such file or directory
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory
 *** done
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
index 8abfde7..41324d5 100644
--- a/tests/qemu-iotests/082.out
+++ b/tests/qemu-iotests/082.out
@@ -326,10 +326,10 @@ preallocation    Preallocation mode (allowed values: off, metadata, falloc, full
 lazy_refcounts   Postpone refcount updates
 Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
-qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open file: No such file or directory
+qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,help': No such file or directory
 Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
-qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open file: No such file or directory
+qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,?': No such file or directory
 Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
 qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2,
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
index de8f529..6c6b210 100644
--- a/tests/qemu-iotests/114.out
+++ b/tests/qemu-iotests/114.out
@@ -7,7 +7,7 @@ virtual size: 64M (67108864 bytes)
 cluster_size: 65536
 backing file: TEST_DIR/t.IMGFMT.base
 backing file format: foo
-qemu-io: can't open device TEST_DIR/t.qcow2: Unknown driver 'foo'
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
 read 4096/4096 bytes at offset 0
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
--
1.8.3.1
SOURCES/kvm-block-Propagate-error-in-bdrv_img_create.patch
New file
@@ -0,0 +1,55 @@
From 3b439999998f800a1a09d6bb779e9f3eef4f1eb9 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Wed, 22 Jul 2015 16:24:56 +0200
Subject: [PATCH 4/5] block: Propagate error in bdrv_img_create()
Message-id: <1437582297-9244-3-git-send-email-mreitz@redhat.com>
Patchwork-id: 67107
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/3] block: Propagate error in bdrv_img_create()
Bugzilla: 1238639
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
If the specified backing file could not be opened, do not generate a new
error message which contains the message which has been generated by
bdrv_open(), but just propagate the latter.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e56934becea70817124be1534f4289ce7d8f6733)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
    block.c
A conflict in the code being removed due to
83d0521a1e35989b0cb7235aef48455fedda3ca4 missing downstream.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c | 5 -----
 1 file changed, 5 deletions(-)
diff --git a/block.c b/block.c
index dedfa52..bc6e75c 100644
--- a/block.c
+++ b/block.c
@@ -5489,11 +5489,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
             ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
                             backing_drv, &local_err);
             if (ret < 0) {
-                error_setg_errno(errp, -ret, "Could not open '%s': %s",
-                                 backing_file->value.s,
-                                 error_get_pretty(local_err));
-                error_free(local_err);
-                local_err = NULL;
                 goto out;
             }
             bdrv_get_geometry(bs, &size);
--
1.8.3.1
SOURCES/kvm-block-Respect-underlying-file-s-EOF.patch
New file
@@ -0,0 +1,65 @@
From 69fe324e32aad7e1afc6ad14021a6a08ad52646c Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Sat, 13 Jun 2015 16:22:27 +0200
Subject: [PATCH 33/42] block: Respect underlying file's EOF
Message-id: <1434212556-3927-34-git-send-email-mreitz@redhat.com>
Patchwork-id: 66052
O-Subject: [RHEL-7.2 qemu-kvm PATCH 33/42] block: Respect underlying file's EOF
Bugzilla: 1129893
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
BZ: 1129893
When falling through to the underlying file in
bdrv_co_get_block_status(), if it returns that the query offset is
beyond the file end (by setting *pnum to 0), return the range to be
zero and do not let the number of sectors for which information could be
obtained be overwritten.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 59c9a95fd29cfb3296ee58e8a446df251d14a459)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index 22ab762..fa6e192 100644
--- a/block.c
+++ b/block.c
@@ -3797,13 +3797,24 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
     if (bs->file &&
         (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
         (ret & BDRV_BLOCK_OFFSET_VALID)) {
+        int file_pnum;
+
         ret2 = bdrv_co_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
-                                        *pnum, pnum);
+                                        *pnum, &file_pnum);
         if (ret2 >= 0) {
             /* Ignore errors.  This is just providing extra information, it
              * is useful but not necessary.
              */
-            ret |= (ret2 & BDRV_BLOCK_ZERO);
+            if (!file_pnum) {
+                /* !file_pnum indicates an offset at or beyond the EOF; it is
+                 * perfectly valid for the format block driver to point to such
+                 * offsets, so catch it and mark everything as zero */
+                ret |= BDRV_BLOCK_ZERO;
+            } else {
+                /* Limit request to the range reported by the protocol driver */
+                *pnum = file_pnum;
+                ret |= (ret2 & BDRV_BLOCK_ZERO);
+            }
         }
     }
--
1.8.3.1
SOURCES/kvm-block-coverity-fix-check-return-value-for-fcntl-in-g.patch
New file
@@ -0,0 +1,51 @@
From 25730930b496dd639afe8906744ce9ebeb7db7e9 Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Wed, 5 Aug 2015 14:38:26 +0200
Subject: [PATCH 3/3] block: coverity fix: check return value for fcntl in
 gluster
Message-id: <9a482772dc4e110d2a774bbed0e1dbecdaaec43e.1438784597.git.jcody@redhat.com>
Patchwork-id: 67323
O-Subject: [RHEL-7.2 qemu-kvm PATCH v3] block: coverity fix: check return value for fcntl in gluster
Bugzilla: 1219217
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Check return value in the Gluster driver for fcntl, as pointed
out by coverity.
Cleanup of s->fds is done inline in the error handling for the fcntl()
call, rather than in the function cleanup, to keep changes minimal for
future backports.
Downstream-only, as upstream Gluster driver does not use fcntl anymore.
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/gluster.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/block/gluster.c b/block/gluster.c
index 5f85799..1793386 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -357,7 +357,13 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,
         ret = -errno;
         goto out;
     }
-    fcntl(s->fds[GLUSTER_FD_READ], F_SETFL, O_NONBLOCK);
+    ret = fcntl(s->fds[GLUSTER_FD_READ], F_SETFL, O_NONBLOCK);
+    if (ret < 0) {
+        ret = -errno;
+        close(s->fds[GLUSTER_FD_READ]);
+        close(s->fds[GLUSTER_FD_WRITE]);
+        goto out;
+    }
     qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ],
         qemu_gluster_aio_event_reader, NULL, qemu_gluster_aio_flush_cb, s);
--
1.8.3.1
SOURCES/kvm-block-curl-Don-t-lose-original-error-when-a-connecti.patch
New file
@@ -0,0 +1,100 @@
From 264a2066904d31c46860e0bac8790d57e6498b80 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Thu, 16 Jul 2015 15:41:54 +0200
Subject: [PATCH 1/5] block/curl: Don't lose original error when a connection
 fails.
Message-id: <1437061314-4775-1-git-send-email-rjones@redhat.com>
Patchwork-id: 67043
O-Subject: [RHEL-7.2 qemu-kvm PATCH v3] block/curl: Don't lose original error when a connection fails.
Bugzilla: 1235812
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: "Richard W.M. Jones" <rjones@redhat.com>
Currently if qemu is connected to a curl source (eg. web server), and
the web server fails / times out / dies, you always see a bogus EIO
"Input/output error".
For example, choose a large file located on any local webserver which
you control:
  $ qemu-img convert -p http://example.com/large.iso /tmp/test
Once it starts copying the file, stop the webserver and you will see
qemu-img fail with:
  qemu-img: error while reading sector 61440: Input/output error
This patch does two things: Firstly print the actual error from curl
so it doesn't get lost.  Secondly, change EIO to EPROTO.  EPROTO is a
POSIX.1 compatible errno which more accurately reflects that there was
a protocol error, rather than some kind of hardware failure.
After this patch is applied, the error changes to:
  $ qemu-img convert -p http://example.com/large.iso /tmp/test
  qemu-img: curl: transfer closed with 469989 bytes remaining to read
  qemu-img: error while reading sector 16384: Protocol error
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
BZ: https://bugzilla.redhat.com/1235812
Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=9529354
Upstream-status: 796a060bc0fab40953997976a2e30d9d6235bc7b
---
 block/curl.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/curl.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/block/curl.c b/block/curl.c
index 3088329..dfa8cee 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include "qemu-common.h"
+#include "qemu/error-report.h"
 #include "block/block_int.h"
 #include "qapi/qmp/qbool.h"
 #include <curl/curl.h>
@@ -294,6 +295,18 @@ static void curl_multi_check_completion(BDRVCURLState *s)
             /* ACBs for successful messages get completed in curl_read_cb */
             if (msg->data.result != CURLE_OK) {
                 int i;
+                static int errcount = 100;
+
+                /* Don't lose the original error message from curl, since
+                 * it contains extra data.
+                 */
+                if (errcount > 0) {
+                    error_report("curl: %s", state->errmsg);
+                    if (--errcount == 0) {
+                        error_report("curl: further errors suppressed");
+                    }
+                }
+
                 for (i = 0; i < CURL_NUM_ACB; i++) {
                     CURLAIOCB *acb = state->acb[i];
@@ -301,7 +314,7 @@ static void curl_multi_check_completion(BDRVCURLState *s)
                         continue;
                     }
-                    acb->common.cb(acb->common.opaque, -EIO);
+                    acb->common.cb(acb->common.opaque, -EPROTO);
                     qemu_aio_release(acb);
                     state->acb[i] = NULL;
                 }
--
1.8.3.1
SOURCES/kvm-block-curl-Implement-the-libcurl-timer-callback-inte.patch
New file
@@ -0,0 +1,200 @@
From a8b59fd3d7aa9f6a16caf4c13534039a81552118 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Thu, 11 Jun 2015 11:40:14 +0200
Subject: [PATCH 14/30] block/curl: Implement the libcurl timer callback
 interface
Message-id: <1434022828-13037-8-git-send-email-rjones@redhat.com>
Patchwork-id: 65842
O-Subject: [RHEL-7.2 qemu-kvm v3 PATCH 07/21] block/curl: Implement the libcurl timer callback interface
Bugzilla: 1226684
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Peter Maydell <peter.maydell@linaro.org>
libcurl versions 7.16.0 and later have a timer callback interface which
must be implemented in order for libcurl to make forward progress (it
will sometimes rely on being called back on the timeout if there are
no file descriptors registered). Implement the callback, and use a
QEMU AIO timer to ensure we prod libcurl again when it asks us to.
Based on Peter's original patch plus my fix to add curl_multi_timeout_do.
Should compile just fine even on older versions of libcurl.
I also tried copy-on-read and streaming:
    $ ./qemu-img create -f qcow2 -o \
         backing_file=http://download.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso \
         foo.qcow2 1G
    $ x86_64-softmmu/qemu-system-x86_64 \
         -drive if=none,file=foo.qcow2,copy-on-read=on,id=cd \
         -device ide-cd,drive=cd --enable-kvm -m 1024
Direct http usage is probably too slow, but with copy-on-read ultimately
the image does boot!
After some time, streaming gets canceled by an EIO, which needs further
investigation.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Upstream-status: 031fd1be5618c347f9aeb44ec294f14a541e42b2
This patch is modified from upstream by adapting the patch
to use the timers API from qemu 1.5.3.  (Thanks: Kevin Wolf)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/curl.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 70 insertions(+), 11 deletions(-)
diff --git a/block/curl.c b/block/curl.c
index 7569dd5..a6631fe 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -34,6 +34,11 @@
 #define DPRINTF(fmt, ...) do { } while (0)
 #endif
+#if LIBCURL_VERSION_NUM >= 0x071000
+/* The multi interface timer callback was introduced in 7.16.0 */
+#define NEED_CURL_TIMER_CALLBACK
+#endif
+
 #define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \
                    CURLPROTO_FTP | CURLPROTO_FTPS | \
                    CURLPROTO_TFTP)
@@ -77,6 +82,7 @@ typedef struct CURLState
 typedef struct BDRVCURLState {
     CURLM *multi;
+    QEMUTimer *timer;
     size_t len;
     CURLState states[CURL_NUM_STATES];
     char *url;
@@ -87,6 +93,23 @@ static void curl_clean_state(CURLState *s);
 static void curl_multi_do(void *arg);
 static int curl_aio_flush(void *opaque);
+#ifdef NEED_CURL_TIMER_CALLBACK
+static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
+{
+    BDRVCURLState *s = opaque;
+
+    DPRINTF("CURL: timer callback timeout_ms %ld\n", timeout_ms);
+    if (timeout_ms == -1) {
+        qemu_del_timer(s->timer);
+    } else {
+        int64_t timeout_ns = (int64_t)timeout_ms * 1000 * 1000;
+        qemu_mod_timer(s->timer,
+                  qemu_get_clock_ns(rt_clock) + timeout_ns);
+    }
+    return 0;
+}
+#endif
+
 static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
                         void *s, void *sp)
 {
@@ -213,20 +236,10 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
     return FIND_RET_NONE;
 }
-static void curl_multi_do(void *arg)
+static void curl_multi_read(BDRVCURLState *s)
 {
-    BDRVCURLState *s = (BDRVCURLState *)arg;
-    int running;
-    int r;
     int msgs_in_queue;
-    if (!s->multi)
-        return;
-
-    do {
-        r = curl_multi_socket_all(s->multi, &running);
-    } while(r == CURLM_CALL_MULTI_PERFORM);
-
     /* Try to find done transfers, so we can free the easy
      * handle again. */
     do {
@@ -271,6 +284,41 @@ static void curl_multi_do(void *arg)
     } while(msgs_in_queue);
 }
+static void curl_multi_do(void *arg)
+{
+    BDRVCURLState *s = (BDRVCURLState *)arg;
+    int running;
+    int r;
+
+    if (!s->multi) {
+        return;
+    }
+
+    do {
+        r = curl_multi_socket_all(s->multi, &running);
+    } while(r == CURLM_CALL_MULTI_PERFORM);
+
+    curl_multi_read(s);
+}
+
+static void curl_multi_timeout_do(void *arg)
+{
+#ifdef NEED_CURL_TIMER_CALLBACK
+    BDRVCURLState *s = (BDRVCURLState *)arg;
+    int running;
+
+    if (!s->multi) {
+        return;
+    }
+
+    curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
+
+    curl_multi_read(s);
+#else
+    abort();
+#endif
+}
+
 static CURLState *curl_init_state(BDRVCURLState *s)
 {
     CURLState *state = NULL;
@@ -462,12 +510,19 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
     curl_easy_cleanup(state->curl);
     state->curl = NULL;
+    s->timer = qemu_new_timer(rt_clock, SCALE_NS,
+                              curl_multi_timeout_do, s);
+
     // Now we know the file exists and its size, so let's
     // initialize the multi interface!
     s->multi = curl_multi_init();
     curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s);
     curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
+#ifdef NEED_CURL_TIMER_CALLBACK
+    curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
+    curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
+#endif
     curl_multi_do(s);
     qemu_opts_del(opts);
@@ -607,6 +662,10 @@ static void curl_close(BlockDriverState *bs)
     }
     if (s->multi)
         curl_multi_cleanup(s->multi);
+
+    qemu_del_timer(s->timer);
+    qemu_free_timer(s->timer);
+
     g_free(s->url);
 }
--
1.8.3.1
SOURCES/kvm-block-curl-Improve-type-safety-of-s-timeout.patch
New file
@@ -0,0 +1,88 @@
From c44c930396e5c19511f36bc45c3f386966b15f9d Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Thu, 11 Jun 2015 11:40:28 +0200
Subject: [PATCH 28/30] block/curl: Improve type safety of s->timeout.
Message-id: <1434022828-13037-22-git-send-email-rjones@redhat.com>
Patchwork-id: 65856
O-Subject: [RHEL-7.2 qemu-kvm v3 PATCH 21/21] block/curl: Improve type safety of s->timeout.
Bugzilla: 1226684
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: "Richard W.M. Jones" <rjones@redhat.com>
qemu_opt_get_number returns a uint64_t, and curl_easy_setopt expects a
long (not an int).  There is no warning about the latter type error
because curl_easy_setopt uses a varargs argument.
Store the timeout (which is a positive number of seconds) as a
uint64_t.  Check that the number given by the user is reasonable.
Zero is permissible (meaning no timeout is enforced by cURL).
Cast it to long before calling curl_easy_setopt to fix the type error.
Example error message after this change has been applied:
$ ./qemu-img create -f qcow2 /tmp/test.qcow2 \
    -b 'json: { "file.driver":"https",
                "file.url":"https://foo/bar",
                "file.timeout":-1 }'
qemu-img: /tmp/test.qcow2: Could not open 'json: { "file.driver":"https", "file.url":"https://foo/bar", "file.timeout":-1 }': timeout parameter is too large or negative: Invalid argument
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Upstream-status: f76faeda4bd59f972d09dd9d954297f17c21dd60
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/curl.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/block/curl.c b/block/curl.c
index 5b407aa..3088329 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -64,6 +64,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
 #define SECTOR_SIZE     512
 #define READ_AHEAD_DEFAULT (256 * 1024)
 #define CURL_TIMEOUT_DEFAULT 5
+#define CURL_TIMEOUT_MAX 10000
 #define FIND_RET_NONE   0
 #define FIND_RET_OK     1
@@ -112,7 +113,7 @@ typedef struct BDRVCURLState {
     char *url;
     size_t readahead_size;
     bool sslverify;
-    int timeout;
+    uint64_t timeout;
     char *cookie;
     bool accept_range;
 } BDRVCURLState;
@@ -387,7 +388,7 @@ static CURLState *curl_init_state(BDRVCURLState *s)
         if (s->cookie) {
             curl_easy_setopt(state->curl, CURLOPT_COOKIE, s->cookie);
         }
-        curl_easy_setopt(state->curl, CURLOPT_TIMEOUT, s->timeout);
+        curl_easy_setopt(state->curl, CURLOPT_TIMEOUT, (long)s->timeout);
         curl_easy_setopt(state->curl, CURLOPT_WRITEFUNCTION,
                          (void *)curl_read_cb);
         curl_easy_setopt(state->curl, CURLOPT_WRITEDATA, (void *)state);
@@ -496,6 +497,10 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
     s->timeout = qemu_opt_get_number(opts, CURL_BLOCK_OPT_TIMEOUT,
                                      CURL_TIMEOUT_DEFAULT);
+    if (s->timeout > CURL_TIMEOUT_MAX) {
+        error_setg(errp, "timeout parameter is too large or negative");
+        goto out_noclean;
+    }
     s->sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY, true);
--
1.8.3.1
SOURCES/kvm-block-qemu-iotests-add-check-for-multiplication-over.patch
New file
@@ -0,0 +1,121 @@
From 119ce531952beab96a8b807721e2180d99382073 Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Wed, 29 Jul 2015 16:59:55 +0200
Subject: [PATCH 04/13] block: qemu-iotests - add check for multiplication
 overflow in vpc
Message-id: <9e859f3912d1852e48fb7e25a3679bd74500c36d.1438188988.git.jcody@redhat.com>
Patchwork-id: 67198
O-Subject: [RHEL-7.2 qemu-kvm PATCH 3/3] block: qemu-iotests - add check for multiplication overflow in vpc
Bugzilla: 1217349
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
This checks that VPC is able to successfully fail (without segfault)
on an image file with a max_table_entries that exceeds 0x40000000.
This table entry is within the valid range for VPC (although too large
for this sample image).
Cc: qemu-stable@nongnu.org
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 77c102c26ead946fe7589d4bddcdfa5cb431ebfe)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
    tests/qemu-iotests/group
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/135     | 54 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/135.out |  5 +++++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 60 insertions(+)
 create mode 100755 tests/qemu-iotests/135
 create mode 100644 tests/qemu-iotests/135.out
diff --git a/tests/qemu-iotests/135 b/tests/qemu-iotests/135
new file mode 100755
index 0000000..16bf736
--- /dev/null
+++ b/tests/qemu-iotests/135
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# Test VPC open of image with large Max Table Entries value.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=jcody@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1    # failure is the default!
+
+_cleanup()
+{
+    _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt vpc
+_supported_proto generic
+_supported_os Linux
+
+_use_sample_img afl5.img.bz2
+
+echo
+echo "=== Verify image open and failure ===="
+$QEMU_IMG info "$TEST_IMG" 2>&1| _filter_testdir
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/135.out b/tests/qemu-iotests/135.out
new file mode 100644
index 0000000..793898b
--- /dev/null
+++ b/tests/qemu-iotests/135.out
@@ -0,0 +1,5 @@
+QA output created by 135
+
+=== Verify image open and failure ====
+qemu-img: Could not open 'TEST_DIR/afl5.img': Max Table Entries too large (1073741825)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 0644c42..58b3d05 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -92,3 +92,4 @@
 114 rw auto quick
 121 rw auto
 130 rw auto quick
+135 rw auto
--
1.8.3.1
SOURCES/kvm-block-ssh-Drop-superfluous-libssh2_session_last_errn.patch
New file
@@ -0,0 +1,60 @@
From 8d385a8bc9d20d1c0ec09579f14a98294b448985 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Mon, 8 Jun 2015 11:56:55 +0200
Subject: [PATCH 02/30] block/ssh: Drop superfluous
 libssh2_session_last_errno() calls
Message-id: <1433764620-20506-2-git-send-email-rjones@redhat.com>
Patchwork-id: 65477
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/6] block/ssh: Drop superfluous libssh2_session_last_errno() calls
Bugzilla: 1226683
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Markus Armbruster <armbru@redhat.com>
libssh2_session_last_error() already returns the error code.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Upstream-status: 04bc7c0e38fc77afc116031f1e25af80374b1971
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/ssh.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/block/ssh.c b/block/ssh.c
index fa3c78d..1f7c6ed 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -121,10 +121,9 @@ session_error_report(BDRVSSHState *s, const char *fs, ...)
         char *ssh_err;
         int ssh_err_code;
-        libssh2_session_last_error((s)->session, &ssh_err, NULL, 0);
         /* This is not an errno.  See <libssh2.h>. */
-        ssh_err_code = libssh2_session_last_errno((s)->session);
-
+        ssh_err_code = libssh2_session_last_error(s->session,
+                                                  &ssh_err, NULL, 0);
         error_printf(": %s (libssh2 error code: %d)", ssh_err, ssh_err_code);
     }
@@ -145,9 +144,9 @@ sftp_error_report(BDRVSSHState *s, const char *fs, ...)
         int ssh_err_code;
         unsigned long sftp_err_code;
-        libssh2_session_last_error((s)->session, &ssh_err, NULL, 0);
         /* This is not an errno.  See <libssh2.h>. */
-        ssh_err_code = libssh2_session_last_errno((s)->session);
+        ssh_err_code = libssh2_session_last_error(s->session,
+                                                  &ssh_err, NULL, 0);
         /* See <libssh2_sftp.h>. */
         sftp_err_code = libssh2_sftp_last_error((s)->sftp);
--
1.8.3.1
SOURCES/kvm-block-ssh-Propagate-errors-through-authenticate.patch
New file
@@ -0,0 +1,106 @@
From aa59c26b76954860b4c7f7e57d1d4b8b99ccfa6f Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Mon, 8 Jun 2015 11:56:57 +0200
Subject: [PATCH 04/30] block/ssh: Propagate errors through authenticate()
Message-id: <1433764620-20506-4-git-send-email-rjones@redhat.com>
Patchwork-id: 65478
O-Subject: [RHEL-7.2 qemu-kvm PATCH 3/6] block/ssh: Propagate errors through authenticate()
Bugzilla: 1226683
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Upstream-status: 4618e658e6dadd1ba53585157984eac71cb706c6
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/ssh.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/block/ssh.c b/block/ssh.c
index 6ffcff1..5908e6d 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -434,7 +434,7 @@ static int check_host_key(BDRVSSHState *s, const char *host, int port,
     return -EINVAL;
 }
-static int authenticate(BDRVSSHState *s, const char *user)
+static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
 {
     int r, ret;
     const char *userauthlist;
@@ -445,7 +445,8 @@ static int authenticate(BDRVSSHState *s, const char *user)
     userauthlist = libssh2_userauth_list(s->session, user, strlen(user));
     if (strstr(userauthlist, "publickey") == NULL) {
         ret = -EPERM;
-        error_report("remote server does not support \"publickey\" authentication");
+        error_setg(errp,
+                "remote server does not support \"publickey\" authentication");
         goto out;
     }
@@ -453,17 +454,18 @@ static int authenticate(BDRVSSHState *s, const char *user)
     agent = libssh2_agent_init(s->session);
     if (!agent) {
         ret = -EINVAL;
-        session_error_report(s, "failed to initialize ssh-agent support");
+        session_error_setg(errp, s, "failed to initialize ssh-agent support");
         goto out;
     }
     if (libssh2_agent_connect(agent)) {
         ret = -ECONNREFUSED;
-        session_error_report(s, "failed to connect to ssh-agent");
+        session_error_setg(errp, s, "failed to connect to ssh-agent");
         goto out;
     }
     if (libssh2_agent_list_identities(agent)) {
         ret = -EINVAL;
-        session_error_report(s, "failed requesting identities from ssh-agent");
+        session_error_setg(errp, s,
+                           "failed requesting identities from ssh-agent");
         goto out;
     }
@@ -474,7 +476,8 @@ static int authenticate(BDRVSSHState *s, const char *user)
         }
         if (r < 0) {
             ret = -EINVAL;
-            session_error_report(s, "failed to obtain identity from ssh-agent");
+            session_error_setg(errp, s,
+                               "failed to obtain identity from ssh-agent");
             goto out;
         }
         r = libssh2_agent_userauth(agent, user, identity);
@@ -488,8 +491,8 @@ static int authenticate(BDRVSSHState *s, const char *user)
     }
     ret = -EPERM;
-    error_report("failed to authenticate using publickey authentication "
-                 "and the identities held by your ssh-agent");
+    error_setg(errp, "failed to authenticate using publickey authentication "
+               "and the identities held by your ssh-agent");
  out:
     if (agent != NULL) {
@@ -577,8 +580,10 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
     }
     /* Authenticate. */
-    ret = authenticate(s, user);
+    ret = authenticate(s, user, &err);
     if (ret < 0) {
+        qerror_report_err(err);
+        error_free(err);
         goto err;
     }
--
1.8.3.1
SOURCES/kvm-block-ssh-Propagate-errors-through-check_host_key.patch
New file
@@ -0,0 +1,193 @@
From 6151164b6f33870c511a7f5f0f64356bb8fe2ff2 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Mon, 8 Jun 2015 11:56:56 +0200
Subject: [PATCH 03/30] block/ssh: Propagate errors through check_host_key()
Message-id: <1433764620-20506-3-git-send-email-rjones@redhat.com>
Patchwork-id: 65479
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/6] block/ssh: Propagate errors through check_host_key()
Bugzilla: 1226683
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Upstream-status: 01c2b265fce921d6460e06f5af4dfb405119cbab
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/ssh.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 49 insertions(+), 19 deletions(-)
diff --git a/block/ssh.c b/block/ssh.c
index 1f7c6ed..6ffcff1 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -106,6 +106,31 @@ static void ssh_state_free(BDRVSSHState *s)
     }
 }
+static void GCC_FMT_ATTR(3, 4)
+session_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...)
+{
+    va_list args;
+    char *msg;
+
+    va_start(args, fs);
+    msg = g_strdup_vprintf(fs, args);
+    va_end(args);
+
+    if (s->session) {
+        char *ssh_err;
+        int ssh_err_code;
+
+        /* This is not an errno.  See <libssh2.h>. */
+        ssh_err_code = libssh2_session_last_error(s->session,
+                                                  &ssh_err, NULL, 0);
+        error_setg(errp, "%s: %s (libssh2 error code: %d)",
+                   msg, ssh_err, ssh_err_code);
+    } else {
+        error_setg(errp, "%s", msg);
+    }
+    g_free(msg);
+}
+
 /* Wrappers around error_report which make sure to dump as much
  * information from libssh2 as possible.
  */
@@ -242,7 +267,7 @@ static void ssh_parse_filename(const char *filename, QDict *options,
 }
 static int check_host_key_knownhosts(BDRVSSHState *s,
-                                     const char *host, int port)
+                                     const char *host, int port, Error **errp)
 {
     const char *home;
     char *knh_file = NULL;
@@ -256,14 +281,15 @@ static int check_host_key_knownhosts(BDRVSSHState *s,
     hostkey = libssh2_session_hostkey(s->session, &len, &type);
     if (!hostkey) {
         ret = -EINVAL;
-        session_error_report(s, "failed to read remote host key");
+        session_error_setg(errp, s, "failed to read remote host key");
         goto out;
     }
     knh = libssh2_knownhost_init(s->session);
     if (!knh) {
         ret = -EINVAL;
-        session_error_report(s, "failed to initialize known hosts support");
+        session_error_setg(errp, s,
+                           "failed to initialize known hosts support");
         goto out;
     }
@@ -288,21 +314,23 @@ static int check_host_key_knownhosts(BDRVSSHState *s,
         break;
     case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
         ret = -EINVAL;
-        session_error_report(s, "host key does not match the one in known_hosts (found key %s)",
-                             found->key);
+        session_error_setg(errp, s,
+                      "host key does not match the one in known_hosts"
+                      " (found key %s)", found->key);
         goto out;
     case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
         ret = -EINVAL;
-        session_error_report(s, "no host key was found in known_hosts");
+        session_error_setg(errp, s, "no host key was found in known_hosts");
         goto out;
     case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
         ret = -EINVAL;
-        session_error_report(s, "failure matching the host key with known_hosts");
+        session_error_setg(errp, s,
+                      "failure matching the host key with known_hosts");
         goto out;
     default:
         ret = -EINVAL;
-        session_error_report(s, "unknown error matching the host key with known_hosts (%d)",
-                             r);
+        session_error_setg(errp, s, "unknown error matching the host key"
+                      " with known_hosts (%d)", r);
         goto out;
     }
@@ -357,20 +385,20 @@ static int compare_fingerprint(const unsigned char *fingerprint, size_t len,
 static int
 check_host_key_hash(BDRVSSHState *s, const char *hash,
-                    int hash_type, size_t fingerprint_len)
+                    int hash_type, size_t fingerprint_len, Error **errp)
 {
     const char *fingerprint;
     fingerprint = libssh2_hostkey_hash(s->session, hash_type);
     if (!fingerprint) {
-        session_error_report(s, "failed to read remote host key");
+        session_error_setg(errp, s, "failed to read remote host key");
         return -EINVAL;
     }
     if(compare_fingerprint((unsigned char *) fingerprint, fingerprint_len,
                            hash) != 0) {
-        error_report("remote host key does not match host_key_check '%s'",
-                     hash);
+        error_setg(errp, "remote host key does not match host_key_check '%s'",
+                   hash);
         return -EPERM;
     }
@@ -378,7 +406,7 @@ check_host_key_hash(BDRVSSHState *s, const char *hash,
 }
 static int check_host_key(BDRVSSHState *s, const char *host, int port,
-                          const char *host_key_check)
+                          const char *host_key_check, Error **errp)
 {
     /* host_key_check=no */
     if (strcmp(host_key_check, "no") == 0) {
@@ -388,21 +416,21 @@ static int check_host_key(BDRVSSHState *s, const char *host, int port,
     /* host_key_check=md5:xx:yy:zz:... */
     if (strncmp(host_key_check, "md5:", 4) == 0) {
         return check_host_key_hash(s, &host_key_check[4],
-                                   LIBSSH2_HOSTKEY_HASH_MD5, 16);
+                                   LIBSSH2_HOSTKEY_HASH_MD5, 16, errp);
     }
     /* host_key_check=sha1:xx:yy:zz:... */
     if (strncmp(host_key_check, "sha1:", 5) == 0) {
         return check_host_key_hash(s, &host_key_check[5],
-                                   LIBSSH2_HOSTKEY_HASH_SHA1, 20);
+                                   LIBSSH2_HOSTKEY_HASH_SHA1, 20, errp);
     }
     /* host_key_check=yes */
     if (strcmp(host_key_check, "yes") == 0) {
-        return check_host_key_knownhosts(s, host, port);
+        return check_host_key_knownhosts(s, host, port, errp);
     }
-    error_report("unknown host_key_check setting (%s)", host_key_check);
+    error_setg(errp, "unknown host_key_check setting (%s)", host_key_check);
     return -EINVAL;
 }
@@ -541,8 +569,10 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
     }
     /* Check the remote host's key against known_hosts. */
-    ret = check_host_key(s, host, port, host_key_check);
+    ret = check_host_key(s, host, port, host_key_check, &err);
     if (ret < 0) {
+        qerror_report_err(err);
+        error_free(err);
         goto err;
     }
--
1.8.3.1
SOURCES/kvm-block-ssh-Propagate-errors-through-connect_to_ssh.patch
New file
@@ -0,0 +1,143 @@
From bd7acae27a2bc4bc1a7865fdaeb30fd9c3a0430c Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Mon, 8 Jun 2015 11:56:58 +0200
Subject: [PATCH 05/30] block/ssh: Propagate errors through connect_to_ssh()
Message-id: <1433764620-20506-5-git-send-email-rjones@redhat.com>
Patchwork-id: 65480
O-Subject: [RHEL-7.2 qemu-kvm PATCH 4/6] block/ssh: Propagate errors through connect_to_ssh()
Bugzilla: 1226683
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Upstream-status: 5f0c39e59822fdfd6a730824eded06209942e495
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/ssh.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/block/ssh.c b/block/ssh.c
index 5908e6d..07f8a2c 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -506,10 +506,9 @@ static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
 }
 static int connect_to_ssh(BDRVSSHState *s, QDict *options,
-                          int ssh_flags, int creat_mode)
+                          int ssh_flags, int creat_mode, Error **errp)
 {
     int r, ret;
-    Error *err = NULL;
     const char *host, *user, *path, *host_key_check;
     int port;
@@ -528,6 +527,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
     } else {
         user = g_get_user_name();
         if (!user) {
+            error_setg_errno(errp, errno, "Can't get user name");
             ret = -errno;
             goto err;
         }
@@ -544,11 +544,9 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
     s->hostport = g_strdup_printf("%s:%d", host, port);