34b321 import qemu-kvm-1.5.3-126.el7

Authored and Committed by centosrcm 8 years ago
114 files changed. 16387 lines added. 184 lines removed.
SOURCES/kvm-Add-skip_dump-flag-to-ignore-memory-region-during-du.patch
file added
+129
SOURCES/kvm-BlockLimits-introduce-max_transfer_length.patch
file added
+66
SOURCES/kvm-Fix-backport-of-target-i386-add-feature-flags-for-CP.patch
file added
+84
SOURCES/kvm-Make-qemu-io-commands-available-in-HMP.patch
file added
+132
SOURCES/kvm-acpi-add-function-to-extract-oem_id-and-oem_table_id.patch
file added
+89
SOURCES/kvm-acpi-expose-oem_id-and-oem_table_id-in-build_rsdt.patch
file added
+92
SOURCES/kvm-acpi-fix-endian-ness-for-table-ids.patch
file added
+249
SOURCES/kvm-acpi-strip-compiler-info-in-built-in-DSDT.patch
file added
+61
SOURCES/kvm-acpi-support-specified-oem-table-id-for-build_header.patch
file added
+154
SOURCES/kvm-acpi-take-oem_id-in-build_header-optionally.patch
file added
+157
SOURCES/kvm-blkdebug-Add-BLKDBG_FLUSH_TO_OS-DISK-events.patch
file added
+100
SOURCES/kvm-block-backend-expose-bs-bl.max_transfer_length.patch
file added
+66
SOURCES/kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch
file modified
+8 -8
SOURCES/kvm-block-jobs-qemu-kvm-rhel-differentiation.patch
file added
+141
SOURCES/kvm-block-raw-posix-Open-file-descriptor-O_RDWR-to-work-.patch
file added
+68
SOURCES/kvm-block-vmdk-fixed-sizeof-error.patch
file added
+50
SOURCES/kvm-block-vmdk-make-ret-variable-usage-clear.patch
file added
+86
SOURCES/kvm-block-vmdk-move-string-allocations-from-stack-to-the.patch
file added
+146
SOURCES/kvm-check-qjson-Add-test-for-JSON-nesting-depth-limit.patch
file added
+73
SOURCES/kvm-cutils-Support-P-and-E-suffixes-in-strtosz.patch
file added
+132
SOURCES/kvm-e1000-eliminate-infinite-loops-on-out-of-bounds-tran.patch
file added
+109
SOURCES/kvm-ehci-clear-suspend-bit-on-detach.patch
file added
+48
SOURCES/kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch
file modified
+4 -3
SOURCES/kvm-hw-input-hid.c-Fix-capslock-hid-code.patch
file added
+50
SOURCES/kvm-ide-test-fix-failure-for-test_flush.patch
file added
+113
SOURCES/kvm-json-parser-drop-superfluous-assignment-for-token-va.patch
file added
+97
SOURCES/kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch
file added
+65
SOURCES/kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch
file added
+64
SOURCES/kvm-nbd-Always-call-close_fn-in-nbd_client_new.patch
file added
+112
SOURCES/kvm-nbd-client_close-on-error-in-nbd_co_client_start.patch
file added
+50
SOURCES/kvm-nbd-server-Coroutine-based-negotiation.patch
file added
+262
SOURCES/kvm-nbd-server-Set-O_NONBLOCK-on-client-fd.patch
file added
+44
SOURCES/kvm-net-Make-qmp_query_rx_filter-with-name-argument-more.patch
file added
+47
SOURCES/kvm-pc-set-the-OEM-fields-in-the-RSDT-and-the-FADT-from-.patch
file added
+133
SOURCES/kvm-qemu-io-Check-for-trailing-chars.patch
file added
+59
SOURCES/kvm-qemu-io-Correct-error-messages.patch
file added
+218
SOURCES/kvm-qemu-io-Don-t-use-global-bs-in-command-implementatio.patch
file added
+737
SOURCES/kvm-qemu-io-Factor-out-qemuio_command.patch
file added
+163
SOURCES/kvm-qemu-io-Handle-cvtnum-errors-in-alloc.patch
file added
+56
SOURCES/kvm-qemu-io-Interface-cleanup.patch
file added
+240
SOURCES/kvm-qemu-io-Make-cvtnum-a-wrapper-around-strtosz_suffix.patch
file added
+112
SOURCES/kvm-qemu-io-Move-command_loop-and-friends.patch
file added
+369
SOURCES/kvm-qemu-io-Move-functions-for-registering-and-running-c.patch
file added
+551
SOURCES/kvm-qemu-io-Move-help-function.patch
file added
+223
SOURCES/kvm-qemu-io-Move-qemu_strsep-to-cutils.c.patch
file added
+107
SOURCES/kvm-qemu-io-Move-quit-function.patch
file added
+119
SOURCES/kvm-qemu-io-Move-remaining-helpers-from-cmd.c.patch
file added
+330
SOURCES/kvm-qemu-io-Remove-unused-args_command.patch
file added
+141
SOURCES/kvm-qemu-io-Split-off-commands-to-qemu-io-cmds.c.patch
file added
+3789
SOURCES/kvm-qemu-io-Use-the-qemu-version-for-V.patch
file added
+54
SOURCES/kvm-qemu-io-fix-cvtnum-lval-types.patch
file added
+360
SOURCES/kvm-qjson-Apply-nesting-limit-more-sanely.patch
file added
+46
SOURCES/kvm-qjson-Convert-to-parser-to-recursive-descent.patch
file added
+328
SOURCES/kvm-qjson-Don-t-crash-when-input-exceeds-nesting-limit.patch
file added
+62
SOURCES/kvm-qjson-Give-each-of-the-six-structural-chars-its-own-.patch
file added
+222
SOURCES/kvm-qjson-Inline-token_is_escape-and-simplify.patch
file added
+97
SOURCES/kvm-qjson-Inline-token_is_keyword-and-simplify.patch
file added
+81
SOURCES/kvm-qjson-Limit-number-of-tokens-in-addition-to-total-si.patch
file added
+59
SOURCES/kvm-qjson-Spell-out-some-silent-assumptions.patch
file added
+81
SOURCES/kvm-qjson-replace-QString-in-JSONLexer-with-GString.patch
file added
+195
SOURCES/kvm-qjson-store-tokens-in-a-GQueue.patch
file added
+332
SOURCES/kvm-qjson-surprise-allocating-6-QObjects-per-token-is-ex.patch
file added
+412
SOURCES/kvm-qxl-Fix-new-function-name-for-spice-server-library.patch
file added
+57
SOURCES/kvm-qxl-allow-to-specify-head-limit-to-qxl-driver.patch
file added
+120
SOURCES/kvm-qxl-factor-out-qxl_get_check_slot_offset.patch
file added
+108
SOURCES/kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch
file added
+79
SOURCES/kvm-qxl-fix-surface-migration.patch
file added
+124
SOURCES/kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch
file added
+109
SOURCES/kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch
file added
+67
SOURCES/kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch
file modified
+6 -6
SOURCES/kvm-rbd-fix-ceph-settings-precedence.patch
file modified
+3 -3
SOURCES/kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch
file modified
+3 -3
SOURCES/kvm-rtl8139-Do-not-consume-the-packet-during-overflow-in.patch
file added
+48
SOURCES/kvm-rtl8139-Fix-receive-buffer-overflow-check.patch
file added
+64
SOURCES/kvm-scsi-Advertise-limits-by-blocksize-not-512.patch
file added
+54
SOURCES/kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch
file added
+67
SOURCES/kvm-seccomp-adding-sysinfo-system-call-to-whitelist.patch
file added
+48
SOURCES/kvm-spice-do-not-require-TCP-ports.patch
file added
+48
SOURCES/kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch
file added
+93
SOURCES/kvm-target-i386-Add-support-for-FEAT_7_0_ECX.patch
file added
+147
SOURCES/kvm-target-i386-add-Skylake-Client-cpu-model.patch
file added
+92
SOURCES/kvm-target-i386-add-feature-flags-for-CPUID-EAX-0xd-ECX-.patch
file added
+168
SOURCES/kvm-target-i386-fix-pcmpxstrx-equal-ordered-strstr-mode.patch
file added
+57
SOURCES/kvm-target-i386-get-put-MSR_TSC_AUX-across-reset-and-mig.patch
file added
+93
SOURCES/kvm-trace-remove-malloc-tracing.patch
file added
+104
SOURCES/kvm-util-Fix-MIN_NON_ZERO.patch
file added
+46
SOURCES/kvm-util-introduce-MIN_NON_ZERO.patch
file added
+52
SOURCES/kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch
file modified
+8 -7
SOURCES/kvm-vga-add-sr_vbe-register-set.patch
file modified
+3 -3
SOURCES/kvm-vga-add-vbe_enabled-helper.patch
file modified
+7 -7
SOURCES/kvm-vga-factor-out-vga-register-setup.patch
file modified
+7 -7
SOURCES/kvm-vga-fix-banked-access-bounds-checking-CVE-2016-xxxx.patchSOURCES/kvm-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch
file renamed
+7 -8
SOURCES/kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
file modified
+7 -7
SOURCES/kvm-vga-update-vga-register-setup-on-vbe-changes.patch
file modified
+7 -7
SOURCES/kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch
file modified
+3 -3
SOURCES/kvm-virtio-recalculate-vq-inuse-after-migration.patch
file added
+73
SOURCES/kvm-virtio-scsi-Prevent-assertion-on-missed-events.patch
file added
+46
SOURCES/kvm-virtio-validate-the-existence-of-handle_output-befor.patch
file added
+59
SOURCES/kvm-vmdk-Check-descriptor-file-length-when-reading-it.patch
file added
+56
SOURCES/kvm-vmdk-Clean-up-descriptor-file-reading.patch
file added
+60
SOURCES/kvm-vmdk-Create-streamOptimized-as-version-3.patch
file added
+51
SOURCES/kvm-vmdk-Fix-calculation-of-block-status-s-offset.patch
file added
+60
SOURCES/kvm-vmdk-Fix-comment-to-match-code-of-extent-lines.patch
file added
+56
SOURCES/kvm-vmdk-Fix-converting-to-streamOptimized.patch
file added
+65
SOURCES/kvm-vmdk-Fix-index_in_cluster-calculation-in-vmdk_co_get.patch
file added
+65
SOURCES/kvm-vmdk-Fix-next_cluster_sector-for-compressed-write.patch
file added
+70
SOURCES/kvm-vmdk-Fix-next_cluster_sector-for-compressed-write2.patch
file added
+55
SOURCES/kvm-vmdk-Leave-bdi-intact-if-ENOTSUP-in-vmdk_get_info.patch
file added
+74
SOURCES/kvm-vmdk-Remove-unnecessary-initialization.patch
file added
+49
SOURCES/kvm-vmdk-Set-errp-on-failures-in-vmdk_open_vmdk4.patch
file added
+62
SOURCES/kvm-vmdk-Use-g_random_int-to-generate-CID.patch
file added
+73
SOURCES/kvm-vmdk-Use-vmdk_find_index_in_cluster-everywhere.patch
file added
+71
SOURCES/kvm-vmdk-Widen-before-shifting-32-bit-header-field.patch
file added
+47
SPECS/qemu-kvm.spec
file modified
+565 -112
    import qemu-kvm-1.5.3-126.el7
    
        
SOURCES/kvm-Add-skip_dump-flag-to-ignore-memory-region-during-du.patch ADDED
@@ -0,0 +1,129 @@
1
+ From 0ae4c882404b4590c34bb9b03a86f9389413fd1c Mon Sep 17 00:00:00 2001
2
+ From: Alex Williamson <alex.williamson@redhat.com>
3
+ Date: Wed, 7 Sep 2016 14:09:52 +0200
4
+ Subject: [PATCH 2/2] Add skip_dump flag to ignore memory region during dump
5
+
6
+ RH-Author: Alex Williamson <alex.williamson@redhat.com>
7
+ Message-id: <20160907140817.21968.47551.stgit@gimli.home>
8
+ Patchwork-id: 72264
9
+ O-Subject: [RHEL7.3 qemu-kvm PATCH v2] Add skip_dump flag to ignore memory region during dump
10
+ Bugzilla: 1373088
11
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
12
+ RH-Acked-by: Auger Eric <eric.auger@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+
15
+ From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
16
+
17
+ Bugzilla: 1373088
18
+ Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=11713365
19
+ Upstream: e4dc3f5909ab90520bc1a27b381c3017ff65ed68
20
+
21
+ The PCI MMIO might be disabled or the device in the reset state.
22
+ Make sure we do not dump these memory regions.
23
+
24
+ Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
25
+ Acked-by: Alex Williamson <alex.williamson@redhat.com>
26
+ CC: Paolo Bonzini <pbonzini@redhat.com>
27
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
28
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
29
+ ---
30
+ hw/misc/vfio.c | 1 +
31
+ include/exec/memory.h | 19 +++++++++++++++++++
32
+ memory.c | 10 ++++++++++
33
+ memory_mapping.c | 3 ++-
34
+ 4 files changed, 32 insertions(+), 1 deletion(-)
35
+
36
+ diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
37
+ index 36b9832..4fdc09a 100644
38
+ --- a/hw/misc/vfio.c
39
+ +++ b/hw/misc/vfio.c
40
+ @@ -2596,6 +2596,7 @@ static int vfio_mmap_bar(VFIOBAR *bar, MemoryRegion *mem, MemoryRegion *submem,
41
+ }
42
+
43
+ memory_region_init_ram_ptr(submem, name, size, *map);
44
+ + memory_region_set_skip_dump(submem);
45
+ } else {
46
+ empty_region:
47
+ /* Create a zero sized sub-region to make cleanup easy. */
48
+ diff --git a/include/exec/memory.h b/include/exec/memory.h
49
+ index 3bbe378..448d501 100644
50
+ --- a/include/exec/memory.h
51
+ +++ b/include/exec/memory.h
52
+ @@ -126,6 +126,7 @@ struct MemoryRegion {
53
+ bool terminates;
54
+ bool romd_mode;
55
+ bool ram;
56
+ + bool skip_dump;
57
+ bool readonly; /* For RAM regions */
58
+ bool enabled;
59
+ bool rom_device;
60
+ @@ -353,6 +354,24 @@ uint64_t memory_region_size(MemoryRegion *mr);
61
+ bool memory_region_is_ram(MemoryRegion *mr);
62
+
63
+ /**
64
+ + * memory_region_is_skip_dump: check whether a memory region should not be
65
+ + * dumped
66
+ + *
67
+ + * Returns %true is a memory region should not be dumped(e.g. VFIO BAR MMAP).
68
+ + *
69
+ + * @mr: the memory region being queried
70
+ + */
71
+ +bool memory_region_is_skip_dump(MemoryRegion *mr);
72
+ +
73
+ +/**
74
+ + * memory_region_set_skip_dump: Set skip_dump flag, dump will ignore this memory
75
+ + * region
76
+ + *
77
+ + * @mr: the memory region being queried
78
+ + */
79
+ +void memory_region_set_skip_dump(MemoryRegion *mr);
80
+ +
81
+ +/**
82
+ * memory_region_is_romd: check whether a memory region is in ROMD mode
83
+ *
84
+ * Returns %true if a memory region is a ROM device and currently set to allow
85
+ diff --git a/memory.c b/memory.c
86
+ index a71d096..7bd6e87 100644
87
+ --- a/memory.c
88
+ +++ b/memory.c
89
+ @@ -957,6 +957,11 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
90
+ mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr);
91
+ }
92
+
93
+ +void memory_region_set_skip_dump(MemoryRegion *mr)
94
+ +{
95
+ + mr->skip_dump = true;
96
+ +}
97
+ +
98
+ void memory_region_init_alias(MemoryRegion *mr,
99
+ const char *name,
100
+ MemoryRegion *orig,
101
+ @@ -1047,6 +1052,11 @@ bool memory_region_is_ram(MemoryRegion *mr)
102
+ return mr->ram;
103
+ }
104
+
105
+ +bool memory_region_is_skip_dump(MemoryRegion *mr)
106
+ +{
107
+ + return mr->skip_dump;
108
+ +}
109
+ +
110
+ bool memory_region_is_logging(MemoryRegion *mr)
111
+ {
112
+ return mr->dirty_log_mask;
113
+ diff --git a/memory_mapping.c b/memory_mapping.c
114
+ index 65082d8..a4d59b7 100644
115
+ --- a/memory_mapping.c
116
+ +++ b/memory_mapping.c
117
+ @@ -203,7 +203,8 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
118
+ GuestPhysBlock *predecessor;
119
+
120
+ /* we only care about RAM */
121
+ - if (!memory_region_is_ram(section->mr)) {
122
+ + if (!memory_region_is_ram(section->mr) ||
123
+ + memory_region_is_skip_dump(section->mr)) {
124
+ return;
125
+ }
126
+
127
+ --
128
+ 1.8.3.1
129
+
SOURCES/kvm-BlockLimits-introduce-max_transfer_length.patch ADDED
@@ -0,0 +1,66 @@
1
+ From fea907b6897cb3e644dcee3c537ce6e64d7850ed Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 11 Jul 2016 05:33:35 +0200
4
+ Subject: [PATCH 2/7] BlockLimits: introduce max_transfer_length
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1468215219-30793-3-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 71106
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 2/6] BlockLimits: introduce max_transfer_length
10
+ Bugzilla: 1318199
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Peter Lieven <pl@kamp.de>
16
+
17
+ Signed-off-by: Peter Lieven <pl@kamp.de>
18
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
19
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
+ (cherry picked from commit 2647fab57d5d5e38b36f8dbda367d688045e6a2d)
21
+ Signed-off-by: Fam Zheng <famz@redhat.com>
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+ ---
24
+ block.c | 4 ++++
25
+ include/block/block_int.h | 3 +++
26
+ 2 files changed, 7 insertions(+)
27
+
28
+ diff --git a/block.c b/block.c
29
+ index ecb2b09..ae756aa 100644
30
+ --- a/block.c
31
+ +++ b/block.c
32
+ @@ -481,6 +481,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
33
+ return;
34
+ }
35
+ bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
36
+ + bs->bl.max_transfer_length = bs->file->bl.max_transfer_length;
37
+ bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
38
+ } else {
39
+ bs->bl.opt_mem_alignment = 512;
40
+ @@ -495,6 +496,9 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
41
+ bs->bl.opt_transfer_length =
42
+ MAX(bs->bl.opt_transfer_length,
43
+ bs->backing_hd->bl.opt_transfer_length);
44
+ + bs->bl.max_transfer_length =
45
+ + MIN_NON_ZERO(bs->bl.max_transfer_length,
46
+ + bs->backing_hd->bl.max_transfer_length);
47
+ bs->bl.opt_mem_alignment =
48
+ MAX(bs->bl.opt_mem_alignment,
49
+ bs->backing_hd->bl.opt_mem_alignment);
50
+ diff --git a/include/block/block_int.h b/include/block/block_int.h
51
+ index 3f86649..28c34d8 100644
52
+ --- a/include/block/block_int.h
53
+ +++ b/include/block/block_int.h
54
+ @@ -240,6 +240,9 @@ typedef struct BlockLimits {
55
+ /* optimal transfer length in sectors */
56
+ int opt_transfer_length;
57
+
58
+ + /* maximal transfer length in sectors */
59
+ + int max_transfer_length;
60
+ +
61
+ /* memory alignment so that no bounce buffer is needed */
62
+ size_t opt_mem_alignment;
63
+ } BlockLimits;
64
+ --
65
+ 1.8.3.1
66
+
SOURCES/kvm-Fix-backport-of-target-i386-add-feature-flags-for-CP.patch ADDED
@@ -0,0 +1,84 @@
1
+ From 7530a2f3975b76711467226f8b279baf36d92e46 Mon Sep 17 00:00:00 2001
2
+ From: Eduardo Habkost <ehabkost@redhat.com>
3
+ Date: Tue, 6 Sep 2016 21:45:05 +0200
4
+ Subject: [PATCH 1/2] Fix backport of "target-i386: add feature flags for
5
+ CPUID[EAX=0xd, ECX=1]"
6
+
7
+ RH-Author: Eduardo Habkost <ehabkost@redhat.com>
8
+ Message-id: <1473198305-8442-1-git-send-email-ehabkost@redhat.com>
9
+ Patchwork-id: 72260
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH] Fix backport of "target-i386: add feature flags for CPUID[EAX=0xd, ECX=1]"
11
+ Bugzilla: 1371619
12
+ RH-Acked-by: Bandan Das <bsd@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
15
+
16
+ Upstream status: commit 0bb0b2d2fe7f645ddaf1f0ff40ac669c9feb4aa1
17
+
18
+ commit 5fcaf5176d7545518c76f3aa8ea7ce6fb063c62d (the backport of
19
+ upstream commit 0bb0b2d2fe7f645ddaf1f0ff40ac669c9feb4aa1) had a
20
+ serious bug: as the qemu-kvm-1.5.3 code doesn't have
21
+ FeatureWordInfo and loops for assigning cpu->features,
22
+ cpu->features[FEAT_XSAVE] was always zero, so that commit
23
+ basically cleared all XSAVE feature bits in all CPU models.
24
+
25
+ Fix it by handling FEAT_XSAVE everywhere it matters: in the
26
+ plus_features/minus_features handling, in the loading of CPU
27
+ model definition, and kvm_cpu_fill_host().
28
+
29
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
30
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
31
+ ---
32
+ target-i386/cpu.c | 8 ++++++++
33
+ 1 file changed, 8 insertions(+)
34
+
35
+ diff --git a/target-i386/cpu.c b/target-i386/cpu.c
36
+ index 80106ba..1001c47 100644
37
+ --- a/target-i386/cpu.c
38
+ +++ b/target-i386/cpu.c
39
+ @@ -1201,6 +1201,8 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
40
+ } else {
41
+ x86_cpu_def->features[FEAT_7_0_EBX] = 0;
42
+ }
43
+ + x86_cpu_def->features[FEAT_XSAVE] =
44
+ + kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
45
+
46
+ x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
47
+ x86_cpu_def->features[FEAT_8000_0001_EDX] =
48
+ @@ -1281,6 +1283,9 @@ static int kvm_check_features_against_host(X86CPU *cpu)
49
+ {&env->features[FEAT_7_0_EBX],
50
+ &host_def.features[FEAT_7_0_EBX],
51
+ FEAT_7_0_EBX },
52
+ + {&env->features[FEAT_XSAVE],
53
+ + &host_def.features[FEAT_XSAVE],
54
+ + FEAT_XSAVE },
55
+ {&env->features[FEAT_SVM],
56
+ &host_def.features[FEAT_SVM],
57
+ FEAT_SVM },
58
+ @@ -1819,6 +1824,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
59
+ env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
60
+ env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
61
+ env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
62
+ + env->features[FEAT_XSAVE] |= plus_features[FEAT_XSAVE];
63
+ env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
64
+ env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
65
+ env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
66
+ @@ -1827,6 +1833,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
67
+ env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
68
+ env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
69
+ env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
70
+ + env->features[FEAT_XSAVE] &= ~minus_features[FEAT_XSAVE];
71
+
72
+ out:
73
+ return;
74
+ @@ -1962,6 +1969,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
75
+ env->features[FEAT_SVM] = def->features[FEAT_SVM];
76
+ env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
77
+ env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
78
+ + env->features[FEAT_XSAVE] = def->features[FEAT_XSAVE];
79
+ env->cpuid_xlevel2 = def->xlevel2;
80
+
81
+ object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
82
+ --
83
+ 1.8.3.1
84
+
SOURCES/kvm-Make-qemu-io-commands-available-in-HMP.patch ADDED
@@ -0,0 +1,132 @@
1
+ From 6b7e23d3e8ff46e638c9dcd769681b2e1b9da08e Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:35 +0100
4
+ Subject: [PATCH 16/27] Make qemu-io commands available in HMP
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-17-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68443
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 16/21] Make qemu-io commands available in HMP
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ It was decided to not make this command available in QMP in order to
18
+ make clear that this is not supposed to be a stable API and should be
19
+ used only for testing and debugging purposes.
20
+
21
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
23
+ (cherry picked from commit 587da2c39c9ace168f4d01fa446a54ae998a2553)
24
+ Signed-off-by: John Snow <jsnow@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ Makefile | 2 +-
28
+ Makefile.objs | 1 +
29
+ hmp-commands.hx | 16 ++++++++++++++++
30
+ hmp.c | 18 ++++++++++++++++++
31
+ hmp.h | 1 +
32
+ 5 files changed, 37 insertions(+), 1 deletion(-)
33
+
34
+ diff --git a/Makefile b/Makefile
35
+ index f403057..76eb694 100644
36
+ --- a/Makefile
37
+ +++ b/Makefile
38
+ @@ -205,7 +205,7 @@ qemu-img.o: qemu-img-cmds.h
39
+
40
+ qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
41
+ qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
42
+ -qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o $(block-obj-y) libqemuutil.a libqemustub.a
43
+ +qemu-io$(EXESUF): qemu-io.o $(block-obj-y) libqemuutil.a libqemustub.a
44
+
45
+ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
46
+
47
+ diff --git a/Makefile.objs b/Makefile.objs
48
+ index f83a5b2..74f722e 100644
49
+ --- a/Makefile.objs
50
+ +++ b/Makefile.objs
51
+ @@ -13,6 +13,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
52
+ block-obj-$(CONFIG_WIN32) += aio-win32.o
53
+ block-obj-y += block/
54
+ block-obj-y += qapi-types.o qapi-visit.o
55
+ +block-obj-y += qemu-io-cmds.o
56
+
57
+ block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
58
+ block-obj-y += qemu-coroutine-sleep.o
59
+ diff --git a/hmp-commands.hx b/hmp-commands.hx
60
+ index 58498f7..7e1855a 100644
61
+ --- a/hmp-commands.hx
62
+ +++ b/hmp-commands.hx
63
+ @@ -1592,6 +1592,22 @@ Removes the chardev @var{id}.
64
+ ETEXI
65
+
66
+ {
67
+ + .name = "qemu-io",
68
+ + .args_type = "device:B,command:s",
69
+ + .params = "[device] \"[command]\"",
70
+ + .help = "run a qemu-io command on a block device",
71
+ + .mhandler.cmd = hmp_qemu_io,
72
+ + },
73
+ +
74
+ +STEXI
75
+ +@item qemu-io @var{device} @var{command}
76
+ +@findex qemu-io
77
+ +
78
+ +Executes a qemu-io command on the given block device.
79
+ +
80
+ +ETEXI
81
+ +
82
+ + {
83
+ .name = "info",
84
+ .args_type = "item:s?",
85
+ .params = "[subcommand]",
86
+ diff --git a/hmp.c b/hmp.c
87
+ index 1805926..e1d92f4 100644
88
+ --- a/hmp.c
89
+ +++ b/hmp.c
90
+ @@ -22,6 +22,7 @@
91
+ #include "qemu/sockets.h"
92
+ #include "monitor/monitor.h"
93
+ #include "ui/console.h"
94
+ +#include "qemu-io.h"
95
+
96
+ static void hmp_handle_error(Monitor *mon, Error **errp)
97
+ {
98
+ @@ -1448,3 +1449,20 @@ void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
99
+ qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
100
+ hmp_handle_error(mon, &local_err);
101
+ }
102
+ +
103
+ +void hmp_qemu_io(Monitor *mon, const QDict *qdict)
104
+ +{
105
+ + BlockDriverState *bs;
106
+ + const char* device = qdict_get_str(qdict, "device");
107
+ + const char* command = qdict_get_str(qdict, "command");
108
+ + Error *err = NULL;
109
+ +
110
+ + bs = bdrv_find(device);
111
+ + if (bs) {
112
+ + qemuio_command(bs, command);
113
+ + } else {
114
+ + error_set(&err, QERR_DEVICE_NOT_FOUND, device);
115
+ + }
116
+ +
117
+ + hmp_handle_error(mon, &err);
118
+ +}
119
+ diff --git a/hmp.h b/hmp.h
120
+ index 9b2c9ce..b27ef3d 100644
121
+ --- a/hmp.h
122
+ +++ b/hmp.h
123
+ @@ -86,5 +86,6 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
124
+ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
125
+ void hmp_chardev_add(Monitor *mon, const QDict *qdict);
126
+ void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
127
+ +void hmp_qemu_io(Monitor *mon, const QDict *qdict);
128
+
129
+ #endif
130
+ --
131
+ 1.8.3.1
132
+
SOURCES/kvm-acpi-add-function-to-extract-oem_id-and-oem_table_id.patch ADDED
@@ -0,0 +1,89 @@
1
+ From 5ccdcc1c49246cce9b1536e28a4977c65d72531c Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Wed, 11 May 2016 12:33:47 +0200
4
+ Subject: [PATCH 08/10] acpi: add function to extract oem_id and oem_table_id
5
+ from the user's SLIC
6
+
7
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
8
+ Message-id: <1462970028-10959-7-git-send-email-lersek@redhat.com>
9
+ Patchwork-id: 70383
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 6/7] acpi: add function to extract oem_id and oem_table_id from the user's SLIC
11
+ Bugzilla: 1330969
12
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
13
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
14
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
15
+
16
+ The acpi_get_slic_oem() function stores pointers to these fields in the
17
+ (first) SLIC table that the user passes in with the -acpitable switch.
18
+
19
+ Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
20
+ Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
21
+ Cc: Richard W.M. Jones <rjones@redhat.com>
22
+ Cc: Aleksei Kovura <alex3kov@zoho.com>
23
+ Cc: Michael Tokarev <mjt@tls.msk.ru>
24
+ Cc: Steven Newbury <steve@snewbury.org.uk>
25
+ RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
26
+ LP: https://bugs.launchpad.net/qemu/+bug/1533848
27
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
28
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
29
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
30
+ Reviewed-by: Steven Newbury <steve@snewbury.org.uk>
31
+ (cherry picked from commit 88594e4fd1e916b778968b2bdd8d7375ca2fe8d8)
32
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
33
+ ---
34
+ include/hw/acpi/acpi.h | 7 +++++++
35
+ hw/acpi/core.c | 16 ++++++++++++++++
36
+ 2 files changed, 23 insertions(+)
37
+
38
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
39
+ ---
40
+ hw/acpi/core.c | 16 ++++++++++++++++
41
+ include/hw/acpi/acpi.h | 7 +++++++
42
+ 2 files changed, 23 insertions(+)
43
+
44
+ diff --git a/hw/acpi/core.c b/hw/acpi/core.c
45
+ index 88efba7..99c5918 100644
46
+ --- a/hw/acpi/core.c
47
+ +++ b/hw/acpi/core.c
48
+ @@ -349,6 +349,22 @@ uint8_t *acpi_table_next(uint8_t *current)
49
+ }
50
+ }
51
+
52
+ +int acpi_get_slic_oem(AcpiSlicOem *oem)
53
+ +{
54
+ + uint8_t *u;
55
+ +
56
+ + for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
57
+ + struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length));
58
+ +
59
+ + if (memcmp(hdr->sig, "SLIC", 4) == 0) {
60
+ + oem->id = hdr->oem_id;
61
+ + oem->table_id = hdr->oem_table_id;
62
+ + return 0;
63
+ + }
64
+ + }
65
+ + return -1;
66
+ +}
67
+ +
68
+ static void acpi_notify_wakeup(Notifier *notifier, void *data)
69
+ {
70
+ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
71
+ diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
72
+ index bb7136d..1e59ec9 100644
73
+ --- a/include/hw/acpi/acpi.h
74
+ +++ b/include/hw/acpi/acpi.h
75
+ @@ -171,4 +171,11 @@ unsigned acpi_table_len(void *current);
76
+ void acpi_table_add(const QemuOpts *opts, Error **errp);
77
+ void acpi_table_add_builtin(const QemuOpts *opts, Error **errp);
78
+
79
+ +typedef struct AcpiSlicOem AcpiSlicOem;
80
+ +struct AcpiSlicOem {
81
+ + char *id;
82
+ + char *table_id;
83
+ +};
84
+ +int acpi_get_slic_oem(AcpiSlicOem *oem);
85
+ +
86
+ #endif /* !QEMU_HW_ACPI_H */
87
+ --
88
+ 1.8.3.1
89
+
SOURCES/kvm-acpi-expose-oem_id-and-oem_table_id-in-build_rsdt.patch ADDED
@@ -0,0 +1,92 @@
1
+ From 39f2d80c57f648afd2eab27816e8f93cf48e718d Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Wed, 11 May 2016 12:33:46 +0200
4
+ Subject: [PATCH 07/10] acpi: expose oem_id and oem_table_id in build_rsdt()
5
+
6
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
7
+ Message-id: <1462970028-10959-6-git-send-email-lersek@redhat.com>
8
+ Patchwork-id: 70382
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 5/7] acpi: expose oem_id and oem_table_id in build_rsdt()
10
+ Bugzilla: 1330969
11
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
12
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
14
+
15
+ Since build_rsdt() is implemented as common utility code (in
16
+ "hw/acpi/aml-build.c"), it should expose -- and forward -- the oem_id and
17
+ oem_table_id parameters between board code and the generic build_header()
18
+ function.
19
+
20
+ Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
21
+ Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
22
+ Cc: Shannon Zhao <zhaoshenglong@huawei.com> (maintainer:ARM ACPI Subsystem)
23
+ Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
24
+ Cc: Richard W.M. Jones <rjones@redhat.com>
25
+ Cc: Aleksei Kovura <alex3kov@zoho.com>
26
+ Cc: Michael Tokarev <mjt@tls.msk.ru>
27
+ Cc: Steven Newbury <steve@snewbury.org.uk>
28
+ RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
29
+ LP: https://bugs.launchpad.net/qemu/+bug/1533848
30
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
31
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
32
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
33
+ Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
34
+ (cherry picked from commit 5151355898699eb66fad0a710b8b6011690a0dfc)
35
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
36
+
37
+ Conflicts:
38
+ hw/acpi/aml-build.c
39
+ hw/arm/virt-acpi-build.c
40
+ hw/i386/acpi-build.c
41
+ include/hw/acpi/aml-build.h
42
+
43
+ RHEL-7 backport note: this is actually a manual reimplementation of the
44
+ upstream patch, which is mostly mechanic. A clean cherry-pick would depend
45
+ on a lot of reorganizatorial upstream patches (e.g., 658c27181bf3
46
+ ("hw/i386/acpi-build: move generic acpi building helpers into dedictated
47
+ file")), and many new features that overlap with ACPI generation (e.g.,
48
+ the "virt" machtype of the arm/aarch64 targets).
49
+
50
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
51
+ ---
52
+ hw/i386/acpi-build.c | 7 ++++---
53
+ 1 file changed, 4 insertions(+), 3 deletions(-)
54
+ ---
55
+ hw/i386/acpi-build.c | 7 ++++---
56
+ 1 file changed, 4 insertions(+), 3 deletions(-)
57
+
58
+ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
59
+ index 4839b0e..d9433e6 100644
60
+ --- a/hw/i386/acpi-build.c
61
+ +++ b/hw/i386/acpi-build.c
62
+ @@ -951,7 +951,8 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
63
+
64
+ /* Build final rsdt table */
65
+ static void
66
+ -build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
67
+ +build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
68
+ + const char *oem_id, const char *oem_table_id)
69
+ {
70
+ AcpiRsdtDescriptorRev1 *rsdt;
71
+ size_t rsdt_len;
72
+ @@ -970,7 +971,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
73
+ sizeof(uint32_t));
74
+ }
75
+ build_header(linker, table_data,
76
+ - (void *)rsdt, "RSDT", rsdt_len, 1, NULL, NULL);
77
+ + (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
78
+ }
79
+
80
+ static GArray *
81
+ @@ -1126,7 +1127,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
82
+
83
+ /* RSDT is pointed to by RSDP */
84
+ rsdt = tables->table_data->len;
85
+ - build_rsdt(tables->table_data, tables->linker, table_offsets);
86
+ + build_rsdt(tables->table_data, tables->linker, table_offsets, NULL, NULL);
87
+
88
+ /* RSDP is in FSEG memory, so allocate it separately */
89
+ build_rsdp(tables->rsdp, tables->linker, rsdt);
90
+ --
91
+ 1.8.3.1
92
+
SOURCES/kvm-acpi-fix-endian-ness-for-table-ids.patch ADDED
@@ -0,0 +1,249 @@
1
+ From 87f01cd69488bf39e80c422b92717029fed0bef6 Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Wed, 11 May 2016 12:33:43 +0200
4
+ Subject: [PATCH 04/10] acpi: fix endian-ness for table ids
5
+
6
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
7
+ Message-id: <1462970028-10959-3-git-send-email-lersek@redhat.com>
8
+ Patchwork-id: 70379
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/7] acpi: fix endian-ness for table ids
10
+ Bugzilla: 1330969
11
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
12
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
14
+
15
+ From: "Michael S. Tsirkin" <mst@redhat.com>
16
+
17
+ when using signature for table ID, we forgot to byte-swap it.
18
+ signatures are really ASCII strings, let's treat them as such.
19
+ While at it, get rid of most of _SIGNATURE macros.
20
+
21
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
22
+ (cherry picked from commit 821e3227863ea8db057190e578efa0f1f57ed9de)
23
+
24
+ RHEL-7 backport notes: this patch is being backported only to decrease the
25
+ number of conflicts in the upcoming patches; we only support x86_64 hosts,
26
+ which is unaffected by the endianness issue described in the upstream
27
+ commit message.
28
+
29
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
30
+ ---
31
+ hw/i386/acpi-defs.h | 14 --------------
32
+ hw/i386/acpi-build.c | 31 ++++++++++++++++---------------
33
+ 2 files changed, 16 insertions(+), 29 deletions(-)
34
+
35
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
36
+ ---
37
+ hw/i386/acpi-build.c | 31 ++++++++++++++++---------------
38
+ hw/i386/acpi-defs.h | 14 --------------
39
+ 2 files changed, 16 insertions(+), 29 deletions(-)
40
+
41
+ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
42
+ index a3a4c3b..be32bc3 100644
43
+ --- a/hw/i386/acpi-build.c
44
+ +++ b/hw/i386/acpi-build.c
45
+ @@ -243,14 +243,14 @@ static void acpi_get_pci_info(PcPciInfo *info)
46
+
47
+ static void
48
+ build_header(GArray *linker, GArray *table_data,
49
+ - AcpiTableHeader *h, uint32_t sig, int len, uint8_t rev)
50
+ + AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
51
+ {
52
+ - h->signature = cpu_to_le32(sig);
53
+ + memcpy(&h->signature, sig, 4);
54
+ h->length = cpu_to_le32(len);
55
+ h->revision = rev;
56
+ memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
57
+ memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
58
+ - memcpy(h->oem_table_id + 4, (void *)&sig, 4);
59
+ + memcpy(h->oem_table_id + 4, sig, 4);
60
+ h->oem_revision = cpu_to_le32(1);
61
+ memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
62
+ h->asl_compiler_revision = cpu_to_le32(1);
63
+ @@ -463,7 +463,7 @@ static void
64
+ build_facs(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
65
+ {
66
+ AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);
67
+ - facs->signature = cpu_to_le32(ACPI_FACS_SIGNATURE);
68
+ + memcpy(&facs->signature, "FACS", 4);
69
+ facs->length = cpu_to_le32(sizeof(*facs));
70
+ }
71
+
72
+ @@ -520,7 +520,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
73
+ fadt_setup(fadt, pm);
74
+
75
+ build_header(linker, table_data,
76
+ - (void *)fadt, ACPI_FACP_SIGNATURE, sizeof(*fadt), 1);
77
+ + (void *)fadt, "FACP", sizeof(*fadt), 1);
78
+ }
79
+
80
+ static void
81
+ @@ -589,7 +589,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
82
+ local_nmi->lint = 1; /* ACPI_LINT1 */
83
+
84
+ build_header(linker, table_data,
85
+ - (void *)(table_data->data + madt_start), ACPI_APIC_SIGNATURE,
86
+ + (void *)(table_data->data + madt_start), "APIC",
87
+ table_data->len - madt_start, 1);
88
+ }
89
+
90
+ @@ -782,7 +782,7 @@ build_ssdt(GArray *table_data, GArray *linker,
91
+
92
+ build_header(linker, table_data,
93
+ (void *)(table_data->data + ssdt_start),
94
+ - ACPI_SSDT_SIGNATURE, table_data->len - ssdt_start, 1);
95
+ + "SSDT", table_data->len - ssdt_start, 1);
96
+ }
97
+
98
+ static void
99
+ @@ -797,7 +797,7 @@ build_hpet(GArray *table_data, GArray *linker)
100
+ hpet->timer_block_id = cpu_to_le32(0x8086a201);
101
+ hpet->addr.address = cpu_to_le64(HPET_BASE);
102
+ build_header(linker, table_data,
103
+ - (void *)hpet, ACPI_HPET_SIGNATURE, sizeof(*hpet), 1);
104
+ + (void *)hpet, "HPET", sizeof(*hpet), 1);
105
+ }
106
+
107
+ static void
108
+ @@ -889,7 +889,7 @@ build_srat(GArray *table_data, GArray *linker,
109
+
110
+ build_header(linker, table_data,
111
+ (void *)(table_data->data + srat_start),
112
+ - ACPI_SRAT_SIGNATURE,
113
+ + "SRAT",
114
+ table_data->len - srat_start, 1);
115
+ }
116
+
117
+ @@ -897,7 +897,7 @@ static void
118
+ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
119
+ {
120
+ AcpiTableMcfg *mcfg;
121
+ - uint32_t sig;
122
+ + const char *sig;
123
+ int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
124
+
125
+ mcfg = acpi_data_push(table_data, len);
126
+ @@ -914,9 +914,10 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
127
+ * ACPI spec requires OSPMs to ignore such tables.
128
+ */
129
+ if (info->mcfg_base == PCIE_BASE_ADDR_UNMAPPED) {
130
+ - sig = ACPI_RSRV_SIGNATURE;
131
+ + /* Reserved signature: ignored by OSPM */
132
+ + sig = "QEMU";
133
+ } else {
134
+ - sig = ACPI_MCFG_SIGNATURE;
135
+ + sig = "MCFG";
136
+ }
137
+ build_header(linker, table_data, (void *)mcfg, sig, len, 1);
138
+ }
139
+ @@ -932,7 +933,7 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
140
+ memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
141
+
142
+ memset(dsdt, 0, sizeof *dsdt);
143
+ - build_header(linker, table_data, dsdt, ACPI_DSDT_SIGNATURE,
144
+ + build_header(linker, table_data, dsdt, "DSDT",
145
+ misc->dsdt_size, 1);
146
+ }
147
+
148
+ @@ -957,7 +958,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
149
+ sizeof(uint32_t));
150
+ }
151
+ build_header(linker, table_data,
152
+ - (void *)rsdt, ACPI_RSDT_SIGNATURE, rsdt_len, 1);
153
+ + (void *)rsdt, "RSDT", rsdt_len, 1);
154
+ }
155
+
156
+ static GArray *
157
+ @@ -968,7 +969,7 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
158
+ bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 1,
159
+ true /* fseg memory */);
160
+
161
+ - rsdp->signature = cpu_to_le64(ACPI_RSDP_SIGNATURE);
162
+ + memcpy(&rsdp->signature, "RSD PTR ", 8);
163
+ memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
164
+ rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
165
+ /* Address to be filled by Guest linker */
166
+ diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
167
+ index 78ca204..e93babb 100644
168
+ --- a/hw/i386/acpi-defs.h
169
+ +++ b/hw/i386/acpi-defs.h
170
+ @@ -52,8 +52,6 @@ struct Acpi20GenericAddress {
171
+ } QEMU_PACKED;
172
+ typedef struct Acpi20GenericAddress Acpi20GenericAddress;
173
+
174
+ -#define ACPI_RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR "
175
+ -
176
+ struct AcpiRsdpDescriptor { /* Root System Descriptor Pointer */
177
+ uint64_t signature; /* ACPI signature, contains "RSD PTR " */
178
+ uint8_t checksum; /* To make sum of struct == 0 */
179
+ @@ -92,7 +90,6 @@ typedef struct AcpiTableHeader AcpiTableHeader;
180
+ /*
181
+ * ACPI 1.0 Fixed ACPI Description Table (FADT)
182
+ */
183
+ -#define ACPI_FACP_SIGNATURE 0x50434146 // FACP
184
+ struct AcpiFadtDescriptorRev1
185
+ {
186
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
187
+ @@ -141,7 +138,6 @@ typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
188
+ /*
189
+ * ACPI 1.0 Root System Description Table (RSDT)
190
+ */
191
+ -#define ACPI_RSDT_SIGNATURE 0x54445352 // RSDT
192
+ struct AcpiRsdtDescriptorRev1
193
+ {
194
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
195
+ @@ -153,7 +149,6 @@ typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
196
+ /*
197
+ * ACPI 1.0 Firmware ACPI Control Structure (FACS)
198
+ */
199
+ -#define ACPI_FACS_SIGNATURE 0x53434146 // FACS
200
+ struct AcpiFacsDescriptorRev1
201
+ {
202
+ uint32_t signature; /* ACPI Signature */
203
+ @@ -169,7 +164,6 @@ typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
204
+ /*
205
+ * Differentiated System Description Table (DSDT)
206
+ */
207
+ -#define ACPI_DSDT_SIGNATURE 0x54445344 // DSDT
208
+
209
+ /*
210
+ * MADT values and structures
211
+ @@ -182,7 +176,6 @@ typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
212
+
213
+ /* Master MADT */
214
+
215
+ -#define ACPI_APIC_SIGNATURE 0x43495041 // APIC
216
+ struct AcpiMultipleApicTable
217
+ {
218
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
219
+ @@ -253,7 +246,6 @@ typedef struct AcpiMadtLocalNmi AcpiMadtLocalNmi;
220
+ /*
221
+ * HPET Description Table
222
+ */
223
+ -#define ACPI_HPET_SIGNATURE 0x54455048 // HPET
224
+ struct Acpi20Hpet {
225
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
226
+ uint32_t timer_block_id;
227
+ @@ -268,7 +260,6 @@ typedef struct Acpi20Hpet Acpi20Hpet;
228
+ * SRAT (NUMA topology description) table
229
+ */
230
+
231
+ -#define ACPI_SRAT_SIGNATURE 0x54415253 // SRAT
232
+ struct AcpiSystemResourceAffinityTable
233
+ {
234
+ ACPI_TABLE_HEADER_DEF
235
+ @@ -316,11 +307,6 @@ struct AcpiMcfgAllocation {
236
+ } QEMU_PACKED;
237
+ typedef struct AcpiMcfgAllocation AcpiMcfgAllocation;
238
+
239
+ -#define ACPI_MCFG_SIGNATURE 0x4746434d // MCFG
240
+ -
241
+ -/* Reserved signature: ignored by OSPM */
242
+ -#define ACPI_RSRV_SIGNATURE 0x554d4551 // QEMU
243
+ -
244
+ struct AcpiTableMcfg {
245
+ ACPI_TABLE_HEADER_DEF;
246
+ uint8_t reserved[8];
247
+ --
248
+ 1.8.3.1
249
+
SOURCES/kvm-acpi-strip-compiler-info-in-built-in-DSDT.patch ADDED
@@ -0,0 +1,61 @@
1
+ From 464ceecd1e9c070e613624fb896df54b7e4a3e38 Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Wed, 11 May 2016 12:33:42 +0200
4
+ Subject: [PATCH 03/10] acpi: strip compiler info in built-in DSDT
5
+
6
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
7
+ Message-id: <1462970028-10959-2-git-send-email-lersek@redhat.com>
8
+ Patchwork-id: 70378
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/7] acpi: strip compiler info in built-in DSDT
10
+ Bugzilla: 1330969
11
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
12
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
14
+
15
+ From: "Michael S. Tsirkin" <mst@redhat.com>
16
+
17
+ IASL stores it's revision in each table header it generates.
18
+ That's not nice since guests will see a change each time they move
19
+ between hypervisors. We generally fill our own info for tables, but we
20
+ (and seabios) forgot to do this for the built-in DSDT.
21
+
22
+ Modifications in DSDT table:
23
+ OEM ID: "BXPC" -> "BOCHS "
24
+ OEM Table ID: "BXDSDT" -> "BXPCDSDT"
25
+ Compiler ID: "INTL" -> "BXPC"
26
+ Compiler Version: 0x20130823 -> 0x00000001
27
+
28
+ Tested-by: Marcel Apfelbaum <marcel.a@redhat.com>
29
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
30
+ (cherry picked from commit 53db092ad1c81c30a617f44e83e8fb9e27c001ba)
31
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
32
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
33
+ ---
34
+ hw/i386/acpi-build.c | 8 +++++++-
35
+ 1 file changed, 7 insertions(+), 1 deletion(-)
36
+
37
+ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
38
+ index 8be1286..a3a4c3b 100644
39
+ --- a/hw/i386/acpi-build.c
40
+ +++ b/hw/i386/acpi-build.c
41
+ @@ -924,10 +924,16 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
42
+ static void
43
+ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
44
+ {
45
+ - void *dsdt;
46
+ + AcpiTableHeader *dsdt;
47
+ +
48
+ assert(misc->dsdt_code && misc->dsdt_size);
49
+ +
50
+ dsdt = acpi_data_push(table_data, misc->dsdt_size);
51
+ memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
52
+ +
53
+ + memset(dsdt, 0, sizeof *dsdt);
54
+ + build_header(linker, table_data, dsdt, ACPI_DSDT_SIGNATURE,
55
+ + misc->dsdt_size, 1);
56
+ }
57
+
58
+ /* Build final rsdt table */
59
+ --
60
+ 1.8.3.1
61
+
SOURCES/kvm-acpi-support-specified-oem-table-id-for-build_header.patch ADDED
@@ -0,0 +1,154 @@
1
+ From b36e60614f9c4a6eb3f417422c3cb99402b82963 Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Wed, 11 May 2016 12:33:44 +0200
4
+ Subject: [PATCH 05/10] acpi: support specified oem table id for build_header
5
+
6
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
7
+ Message-id: <1462970028-10959-4-git-send-email-lersek@redhat.com>
8
+ Patchwork-id: 70380
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 3/7] acpi: support specified oem table id for build_header
10
+ Bugzilla: 1330969
11
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
12
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
14
+
15
+ From: Xiao Guangrong <guangrong.xiao@linux.intel.com>
16
+
17
+ Let build_header() support specified OEM table id so that we can build
18
+ multiple SSDT later
19
+
20
+ If the oem table id is not specified (aka, NULL), we use the default id
21
+ instead as the previous behavior
22
+
23
+ Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
25
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
26
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
27
+ (cherry picked from commit 8870ca0e94f2524644812dd759863c0851ffb870)
28
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
29
+
30
+ Conflicts:
31
+ hw/acpi/aml-build.c
32
+ hw/arm/virt-acpi-build.c
33
+ hw/i386/acpi-build.c
34
+ include/hw/acpi/aml-build.h
35
+
36
+ RHEL-7 backport note: this is actually a manual reimplementation of the
37
+ upstream patch, which is mostly mechanic. A clean cherry-pick would depend
38
+ on a lot of reorganizatorial upstream patches (e.g., 658c27181bf3
39
+ ("hw/i386/acpi-build: move generic acpi building helpers into dedictated
40
+ file")), and many new features that overlap with ACPI generation (e.g.,
41
+ the "virt" machtype of the arm/aarch64 targets).
42
+
43
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
44
+ ---
45
+ hw/i386/acpi-build.c | 29 ++++++++++++++++++-----------
46
+ 1 file changed, 18 insertions(+), 11 deletions(-)
47
+ ---
48
+ hw/i386/acpi-build.c | 29 ++++++++++++++++++-----------
49
+ 1 file changed, 18 insertions(+), 11 deletions(-)
50
+
51
+ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
52
+ index be32bc3..a9d9f97 100644
53
+ --- a/hw/i386/acpi-build.c
54
+ +++ b/hw/i386/acpi-build.c
55
+ @@ -243,14 +243,21 @@ static void acpi_get_pci_info(PcPciInfo *info)
56
+
57
+ static void
58
+ build_header(GArray *linker, GArray *table_data,
59
+ - AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
60
+ + AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
61
+ + const char *oem_table_id)
62
+ {
63
+ memcpy(&h->signature, sig, 4);
64
+ h->length = cpu_to_le32(len);
65
+ h->revision = rev;
66
+ memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
67
+ - memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
68
+ - memcpy(h->oem_table_id + 4, sig, 4);
69
+ +
70
+ + if (oem_table_id) {
71
+ + strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
72
+ + } else {
73
+ + memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
74
+ + memcpy(h->oem_table_id + 4, sig, 4);
75
+ + }
76
+ +
77
+ h->oem_revision = cpu_to_le32(1);
78
+ memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
79
+ h->asl_compiler_revision = cpu_to_le32(1);
80
+ @@ -520,7 +527,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
81
+ fadt_setup(fadt, pm);
82
+
83
+ build_header(linker, table_data,
84
+ - (void *)fadt, "FACP", sizeof(*fadt), 1);
85
+ + (void *)fadt, "FACP", sizeof(*fadt), 1, NULL);
86
+ }
87
+
88
+ static void
89
+ @@ -590,7 +597,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
90
+
91
+ build_header(linker, table_data,
92
+ (void *)(table_data->data + madt_start), "APIC",
93
+ - table_data->len - madt_start, 1);
94
+ + table_data->len - madt_start, 1, NULL);
95
+ }
96
+
97
+ /* Encode a hex value */
98
+ @@ -782,7 +789,7 @@ build_ssdt(GArray *table_data, GArray *linker,
99
+
100
+ build_header(linker, table_data,
101
+ (void *)(table_data->data + ssdt_start),
102
+ - "SSDT", table_data->len - ssdt_start, 1);
103
+ + "SSDT", table_data->len - ssdt_start, 1, NULL);
104
+ }
105
+
106
+ static void
107
+ @@ -797,7 +804,7 @@ build_hpet(GArray *table_data, GArray *linker)
108
+ hpet->timer_block_id = cpu_to_le32(0x8086a201);
109
+ hpet->addr.address = cpu_to_le64(HPET_BASE);
110
+ build_header(linker, table_data,
111
+ - (void *)hpet, "HPET", sizeof(*hpet), 1);
112
+ + (void *)hpet, "HPET", sizeof(*hpet), 1, NULL);
113
+ }
114
+
115
+ static void
116
+ @@ -890,7 +897,7 @@ build_srat(GArray *table_data, GArray *linker,
117
+ build_header(linker, table_data,
118
+ (void *)(table_data->data + srat_start),
119
+ "SRAT",
120
+ - table_data->len - srat_start, 1);
121
+ + table_data->len - srat_start, 1, NULL);
122
+ }
123
+
124
+ static void
125
+ @@ -919,7 +926,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
126
+ } else {
127
+ sig = "MCFG";
128
+ }
129
+ - build_header(linker, table_data, (void *)mcfg, sig, len, 1);
130
+ + build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL);
131
+ }
132
+
133
+ static void
134
+ @@ -934,7 +941,7 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
135
+
136
+ memset(dsdt, 0, sizeof *dsdt);
137
+ build_header(linker, table_data, dsdt, "DSDT",
138
+ - misc->dsdt_size, 1);
139
+ + misc->dsdt_size, 1, NULL);
140
+ }
141
+
142
+ /* Build final rsdt table */
143
+ @@ -958,7 +965,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
144
+ sizeof(uint32_t));
145
+ }
146
+ build_header(linker, table_data,
147
+ - (void *)rsdt, "RSDT", rsdt_len, 1);
148
+ + (void *)rsdt, "RSDT", rsdt_len, 1, NULL);
149
+ }
150
+
151
+ static GArray *
152
+ --
153
+ 1.8.3.1
154
+
SOURCES/kvm-acpi-take-oem_id-in-build_header-optionally.patch ADDED
@@ -0,0 +1,157 @@
1
+ From 0decede8a51451da8f5913b0ad13c8e3bdcef582 Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Wed, 11 May 2016 12:33:45 +0200
4
+ Subject: [PATCH 06/10] acpi: take oem_id in build_header(), optionally
5
+
6
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
7
+ Message-id: <1462970028-10959-5-git-send-email-lersek@redhat.com>
8
+ Patchwork-id: 70381
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 4/7] acpi: take oem_id in build_header(), optionally
10
+ Bugzilla: 1330969
11
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
12
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
14
+
15
+ This patch is the continuation of commit 8870ca0e94f2 ("acpi: support
16
+ specified oem table id for build_header"). It will allow us to control the
17
+ OEM ID field too in the SDT header.
18
+
19
+ Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
20
+ Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
21
+ Cc: Xiao Guangrong <guangrong.xiao@linux.intel.com> (maintainer:NVDIMM)
22
+ Cc: Shannon Zhao <zhaoshenglong@huawei.com> (maintainer:ARM ACPI Subsystem)
23
+ Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
24
+ Cc: Richard W.M. Jones <rjones@redhat.com>
25
+ Cc: Aleksei Kovura <alex3kov@zoho.com>
26
+ Cc: Michael Tokarev <mjt@tls.msk.ru>
27
+ Cc: Steven Newbury <steve@snewbury.org.uk>
28
+ RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
29
+ LP: https://bugs.launchpad.net/qemu/+bug/1533848
30
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
31
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
32
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
33
+ Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
34
+ (cherry picked from commit 37ad223c515da2fe9f1c679768cb5ccaa42e57e1)
35
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
36
+
37
+ Conflicts:
38
+ hw/acpi/aml-build.c
39
+ hw/acpi/nvdimm.c
40
+ hw/arm/virt-acpi-build.c
41
+ hw/i386/acpi-build.c
42
+ include/hw/acpi/aml-build.h
43
+
44
+ RHEL-7 backport note: this is actually a manual reimplementation of the
45
+ upstream patch, which is mostly mechanic. A clean cherry-pick would depend
46
+ on a lot of reorganizatorial upstream patches (e.g., 658c27181bf3
47
+ ("hw/i386/acpi-build: move generic acpi building helpers into dedictated
48
+ file")), and many new features that overlap with ACPI generation (e.g.,
49
+ the "virt" machtype of the arm/aarch64 targets).
50
+
51
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
52
+ ---
53
+ hw/i386/acpi-build.c | 25 +++++++++++++++----------
54
+ 1 file changed, 15 insertions(+), 10 deletions(-)
55
+ ---
56
+ hw/i386/acpi-build.c | 25 +++++++++++++++----------
57
+ 1 file changed, 15 insertions(+), 10 deletions(-)
58
+
59
+ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
60
+ index a9d9f97..4839b0e 100644
61
+ --- a/hw/i386/acpi-build.c
62
+ +++ b/hw/i386/acpi-build.c
63
+ @@ -244,12 +244,17 @@ static void acpi_get_pci_info(PcPciInfo *info)
64
+ static void
65
+ build_header(GArray *linker, GArray *table_data,
66
+ AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
67
+ - const char *oem_table_id)
68
+ + const char *oem_id, const char *oem_table_id)
69
+ {
70
+ memcpy(&h->signature, sig, 4);
71
+ h->length = cpu_to_le32(len);
72
+ h->revision = rev;
73
+ - memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
74
+ +
75
+ + if (oem_id) {
76
+ + strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
77
+ + } else {
78
+ + memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
79
+ + }
80
+
81
+ if (oem_table_id) {
82
+ strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
83
+ @@ -527,7 +532,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
84
+ fadt_setup(fadt, pm);
85
+
86
+ build_header(linker, table_data,
87
+ - (void *)fadt, "FACP", sizeof(*fadt), 1, NULL);
88
+ + (void *)fadt, "FACP", sizeof(*fadt), 1, NULL, NULL);
89
+ }
90
+
91
+ static void
92
+ @@ -597,7 +602,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
93
+
94
+ build_header(linker, table_data,
95
+ (void *)(table_data->data + madt_start), "APIC",
96
+ - table_data->len - madt_start, 1, NULL);
97
+ + table_data->len - madt_start, 1, NULL, NULL);
98
+ }
99
+
100
+ /* Encode a hex value */
101
+ @@ -789,7 +794,7 @@ build_ssdt(GArray *table_data, GArray *linker,
102
+
103
+ build_header(linker, table_data,
104
+ (void *)(table_data->data + ssdt_start),
105
+ - "SSDT", table_data->len - ssdt_start, 1, NULL);
106
+ + "SSDT", table_data->len - ssdt_start, 1, NULL, NULL);
107
+ }
108
+
109
+ static void
110
+ @@ -804,7 +809,7 @@ build_hpet(GArray *table_data, GArray *linker)
111
+ hpet->timer_block_id = cpu_to_le32(0x8086a201);
112
+ hpet->addr.address = cpu_to_le64(HPET_BASE);
113
+ build_header(linker, table_data,
114
+ - (void *)hpet, "HPET", sizeof(*hpet), 1, NULL);
115
+ + (void *)hpet, "HPET", sizeof(*hpet), 1, NULL, NULL);
116
+ }
117
+
118
+ static void
119
+ @@ -897,7 +902,7 @@ build_srat(GArray *table_data, GArray *linker,
120
+ build_header(linker, table_data,
121
+ (void *)(table_data->data + srat_start),
122
+ "SRAT",
123
+ - table_data->len - srat_start, 1, NULL);
124
+ + table_data->len - srat_start, 1, NULL, NULL);
125
+ }
126
+
127
+ static void
128
+ @@ -926,7 +931,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
129
+ } else {
130
+ sig = "MCFG";
131
+ }
132
+ - build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL);
133
+ + build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL);
134
+ }
135
+
136
+ static void
137
+ @@ -941,7 +946,7 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
138
+
139
+ memset(dsdt, 0, sizeof *dsdt);
140
+ build_header(linker, table_data, dsdt, "DSDT",
141
+ - misc->dsdt_size, 1, NULL);
142
+ + misc->dsdt_size, 1, NULL, NULL);
143
+ }
144
+
145
+ /* Build final rsdt table */
146
+ @@ -965,7 +970,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
147
+ sizeof(uint32_t));
148
+ }
149
+ build_header(linker, table_data,
150
+ - (void *)rsdt, "RSDT", rsdt_len, 1, NULL);
151
+ + (void *)rsdt, "RSDT", rsdt_len, 1, NULL, NULL);
152
+ }
153
+
154
+ static GArray *
155
+ --
156
+ 1.8.3.1
157
+
SOURCES/kvm-blkdebug-Add-BLKDBG_FLUSH_TO_OS-DISK-events.patch ADDED
@@ -0,0 +1,100 @@
1
+ From 89f3f5eafd6aed8a79b4570553af711dffc3a1d6 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:36 +0100
4
+ Subject: [PATCH 17/27] blkdebug: Add BLKDBG_FLUSH_TO_OS/DISK events
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-18-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68448
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 17/21] blkdebug: Add BLKDBG_FLUSH_TO_OS/DISK events
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
+ (cherry picked from commit bf736fe34caba0688c9095c31b9d097ea15c1296)
20
+ Signed-off-by: John Snow <jsnow@redhat.com>
21
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
22
+
23
+ Conflicts:
24
+ block/blkdebug.c: debug event ordering
25
+ include/block/block.h: debug event ordering
26
+
27
+ Signed-off-by: John Snow <jsnow@redhat.com>
28
+ ---
29
+ block.c | 8 ++++----
30
+ block/blkdebug.c | 3 +++
31
+ include/block/block.h | 3 +++
32
+ 3 files changed, 10 insertions(+), 4 deletions(-)
33
+
34
+ diff --git a/block.c b/block.c
35
+ index bc6e75c..ecb2b09 100644
36
+ --- a/block.c
37
+ +++ b/block.c
38
+ @@ -4026,13 +4026,11 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
39
+
40
+ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
41
+ {
42
+ - BlockDriver *drv = bs->drv;
43
+ -
44
+ - if (!drv || !drv->bdrv_debug_event) {
45
+ + if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
46
+ return;
47
+ }
48
+
49
+ - drv->bdrv_debug_event(bs, event);
50
+ + bs->drv->bdrv_debug_event(bs, event);
51
+ }
52
+
53
+ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
54
+ @@ -4879,6 +4877,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
55
+ }
56
+
57
+ /* Write back cached data to the OS even with cache=unsafe */
58
+ + BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_OS);
59
+ if (bs->drv->bdrv_co_flush_to_os) {
60
+ ret = bs->drv->bdrv_co_flush_to_os(bs);
61
+ if (ret < 0) {
62
+ @@ -4891,6 +4890,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
63
+ goto flush_parent;
64
+ }
65
+
66
+ + BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK);
67
+ if (bs->drv->bdrv_co_flush_to_disk) {
68
+ ret = bs->drv->bdrv_co_flush_to_disk(bs);
69
+ } else if (bs->drv->bdrv_aio_flush) {
70
+ diff --git a/block/blkdebug.c b/block/blkdebug.c
71
+ index c61ce52..8e468b2 100644
72
+ --- a/block/blkdebug.c
73
+ +++ b/block/blkdebug.c
74
+ @@ -184,6 +184,9 @@ static const char *event_names[BLKDBG_EVENT_MAX] = {
75
+ [BLKDBG_CLUSTER_ALLOC_BYTES] = "cluster_alloc_bytes",
76
+ [BLKDBG_CLUSTER_FREE] = "cluster_free",
77
+
78
+ + [BLKDBG_FLUSH_TO_OS] = "flush_to_os",
79
+ + [BLKDBG_FLUSH_TO_DISK] = "flush_to_disk",
80
+ +
81
+ [BLKDBG_PWRITEV_RMW_HEAD] = "pwritev_rmw.head",
82
+ [BLKDBG_PWRITEV_RMW_AFTER_HEAD] = "pwritev_rmw.after_head",
83
+ [BLKDBG_PWRITEV_RMW_TAIL] = "pwritev_rmw.tail",
84
+ diff --git a/include/block/block.h b/include/block/block.h
85
+ index 8339cac..75147b2 100644
86
+ --- a/include/block/block.h
87
+ +++ b/include/block/block.h
88
+ @@ -508,6 +508,9 @@ typedef enum {
89
+ BLKDBG_CLUSTER_ALLOC_BYTES,
90
+ BLKDBG_CLUSTER_FREE,
91
+
92
+ + BLKDBG_FLUSH_TO_OS,
93
+ + BLKDBG_FLUSH_TO_DISK,
94
+ +
95
+ BLKDBG_PWRITEV_RMW_HEAD,
96
+ BLKDBG_PWRITEV_RMW_AFTER_HEAD,
97
+ BLKDBG_PWRITEV_RMW_TAIL,
98
+ --
99
+ 1.8.3.1
100
+
SOURCES/kvm-block-backend-expose-bs-bl.max_transfer_length.patch ADDED
@@ -0,0 +1,66 @@
1
+ From b9d7b6bbaa64404eb9b4a65d0af841bfae5c9089 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 11 Jul 2016 05:33:36 +0200
4
+ Subject: [PATCH 3/7] block-backend: expose bs->bl.max_transfer_length
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1468215219-30793-4-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 71107
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 3/6] block-backend: expose bs->bl.max_transfer_length
10
+ Bugzilla: 1318199
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Peter Lieven <pl@kamp.de>
16
+
17
+ Signed-off-by: Peter Lieven <pl@kamp.de>
18
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
19
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
+ (cherry picked from commit 454057b7d9b9ad141bd5df8c4075745e56b4870f)
21
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
22
+
23
+ Conflicts:
24
+ block/block-backend.c
25
+ include/sysemu/block-backend.h
26
+
27
+ Downstream doesn't have BlockBackend yet, so "blk_" -> "bdrv_" and put
28
+ the function in block.c.
29
+
30
+ Signed-off-by: Fam Zheng <famz@redhat.com>
31
+ ---
32
+ block.c | 5 +++++
33
+ include/block/block.h | 1 +
34
+ 2 files changed, 6 insertions(+)
35
+
36
+ diff --git a/block.c b/block.c
37
+ index ae756aa..bdcd741 100644
38
+ --- a/block.c
39
+ +++ b/block.c
40
+ @@ -3656,6 +3656,11 @@ int bdrv_get_flags(BlockDriverState *bs)
41
+ return bs->open_flags;
42
+ }
43
+
44
+ +int bdrv_get_max_transfer_length(BlockDriverState *bs)
45
+ +{
46
+ + return bs->bl.max_transfer_length;
47
+ +}
48
+ +
49
+ int bdrv_flush_all(void)
50
+ {
51
+ BlockDriverState *bs;
52
+ diff --git a/include/block/block.h b/include/block/block.h
53
+ index 75147b2..d29733a 100644
54
+ --- a/include/block/block.h
55
+ +++ b/include/block/block.h
56
+ @@ -379,6 +379,7 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
57
+ void *opaque);
58
+ const char *bdrv_get_device_name(BlockDriverState *bs);
59
+ int bdrv_get_flags(BlockDriverState *bs);
60
+ +int bdrv_get_max_transfer_length(BlockDriverState *bs);
61
+ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
62
+ const uint8_t *buf, int nb_sectors);
63
+ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
64
+ --
65
+ 1.8.3.1
66
+
SOURCES/kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch CHANGED
@@ -1,16 +1,16 @@
1
- From f5596dffdad4014342239c7d3ec85e637969d2de Mon Sep 17 00:00:00 2001
1
+ From d2291657a3d6100be53008fe8206c9e72b37c584 Mon Sep 17 00:00:00 2001
2
2
From: Fam Zheng <famz@redhat.com>
3
- Date: Fri, 29 Jul 2016 07:54:22 +0200
3
+ Date: Wed, 22 Jun 2016 01:06:15 +0200
4
4
Subject: [PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
5
5
6
6
RH-Author: Fam Zheng <famz@redhat.com>
7
- Message-id: <1469778862-32607-1-git-send-email-famz@redhat.com>
8
- Patchwork-id: 71515
9
- O-Subject: [RHEL-7.2.z qemu-kvm PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
10
- Bugzilla: 1358996
11
- RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7
+ Message-id: <20160622010615.10307-1-famz@redhat.com>
8
+ Patchwork-id: 70730
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
10
+ Bugzilla: 1340929
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
- RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
12
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
13
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
14
14
15
15
From: Peter Lieven <pl@kamp.de>
16
16
SOURCES/kvm-block-jobs-qemu-kvm-rhel-differentiation.patch ADDED
@@ -0,0 +1,141 @@
1
+ From bb8aca64535578520c4b7f5186f9ae5754626694 Mon Sep 17 00:00:00 2001
2
+ From: Jeffrey Cody <jcody@redhat.com>
3
+ Date: Thu, 5 May 2016 19:46:28 +0200
4
+ Subject: [PATCH 10/10] block jobs: qemu-kvm-rhel differentiation
5
+
6
+ RH-Author: Jeffrey Cody <jcody@redhat.com>
7
+ Message-id: <f2ce1dbde4055f710cb6f83e6edd9e93a498b366.1462477116.git.jcody@redhat.com>
8
+ Patchwork-id: 70344
9
+ O-Subject: [RHEL7.3 qemu-kvm-rhel 1/1] block jobs: qemu-kvm-rhel differentiation
10
+ Bugzilla: 1156635
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
14
+
15
+ The conditional block job disablement for RHEL left some QAPI / HMP
16
+ commands in place, that are vestigial without any actual block jobs to
17
+ control.
18
+
19
+ This patch envelopes those block-job related functions in the
20
+ conditional code that is disabled for RHEL:
21
+
22
+ block-job-set-speed
23
+ block-job-cancel
24
+ block-job-pause
25
+ block-job-resume
26
+ block-job-complete
27
+
28
+ Signed-off-by: Jeff Cody <jcody@redhat.com>
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ blockdev.c | 2 +-
32
+ hmp-commands.hx | 2 +-
33
+ hmp.c | 2 +-
34
+ qapi-schema.json | 2 +-
35
+ qmp-commands.hx | 3 ---
36
+ 5 files changed, 4 insertions(+), 7 deletions(-)
37
+
38
+ diff --git a/blockdev.c b/blockdev.c
39
+ index b5792a2..69e951f 100644
40
+ --- a/blockdev.c
41
+ +++ b/blockdev.c
42
+ @@ -1701,7 +1701,6 @@ void qmp_drive_mirror(const char *device, const char *target,
43
+ return;
44
+ }
45
+ }
46
+ -#endif
47
+
48
+ static BlockJob *find_block_job(const char *device)
49
+ {
50
+ @@ -1786,6 +1785,7 @@ void qmp_block_job_complete(const char *device, Error **errp)
51
+ trace_qmp_block_job_complete(job);
52
+ block_job_complete(job, errp);
53
+ }
54
+ +#endif
55
+
56
+ void qmp___com_redhat_change_backing_file(const char *device,
57
+ const char *image_node_name,
58
+ diff --git a/hmp-commands.hx b/hmp-commands.hx
59
+ index 7e1855a..dd528d2 100644
60
+ --- a/hmp-commands.hx
61
+ +++ b/hmp-commands.hx
62
+ @@ -81,7 +81,6 @@ ETEXI
63
+ .help = "copy data from a backing file into a block device",
64
+ .mhandler.cmd = hmp_block_stream,
65
+ },
66
+ -#endif
67
+
68
+ STEXI
69
+ @item block_stream
70
+ @@ -160,6 +159,7 @@ STEXI
71
+ @findex block_job_resume
72
+ Resume a paused block streaming operation.
73
+ ETEXI
74
+ +#endif
75
+
76
+ {
77
+ .name = "eject",
78
+ diff --git a/hmp.c b/hmp.c
79
+ index e1d92f4..fb9b445 100644
80
+ --- a/hmp.c
81
+ +++ b/hmp.c
82
+ @@ -1053,7 +1053,6 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
83
+
84
+ hmp_handle_error(mon, &error);
85
+ }
86
+ -#endif
87
+
88
+ void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
89
+ {
90
+ @@ -1106,6 +1105,7 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
91
+
92
+ hmp_handle_error(mon, &error);
93
+ }
94
+ +#endif
95
+
96
+ typedef struct MigrationStatus
97
+ {
98
+ diff --git a/qapi-schema.json b/qapi-schema.json
99
+ index c8732c1..5138ed9 100644
100
+ --- a/qapi-schema.json
101
+ +++ b/qapi-schema.json
102
+ @@ -2326,7 +2326,6 @@
103
+ { 'command': 'block-stream',
104
+ 'data': { 'device': 'str', '*base': 'str', '*backing-file': 'str',
105
+ '*speed': 'int', '*on-error': 'BlockdevOnError' } }
106
+ -#_end-rhev-only
107
+
108
+ ##
109
+ # @block-job-set-speed:
110
+ @@ -2448,6 +2447,7 @@
111
+ # Since: 1.3
112
+ ##
113
+ { 'command': 'block-job-complete', 'data': { 'device': 'str' } }
114
+ +#_end-rhev-only
115
+
116
+ ##
117
+ # @ObjectTypeInfo:
118
+ diff --git a/qmp-commands.hx b/qmp-commands.hx
119
+ index 22a09be..9522c44 100644
120
+ --- a/qmp-commands.hx
121
+ +++ b/qmp-commands.hx
122
+ @@ -1089,8 +1089,6 @@ Example:
123
+
124
+ EQMP
125
+
126
+ -#endif
127
+ -
128
+ {
129
+ .name = "block-job-set-speed",
130
+ .args_type = "device:B,speed:o",
131
+ @@ -1117,7 +1115,6 @@ EQMP
132
+ .args_type = "device:B",
133
+ .mhandler.cmd_new = qmp_marshal_input_block_job_complete,
134
+ },
135
+ -#ifdef CONFIG_LIVE_BLOCK_OPS
136
+ {
137
+ .name = "transaction",
138
+ .args_type = "actions:q",
139
+ --
140
+ 1.8.3.1
141
+
SOURCES/kvm-block-raw-posix-Open-file-descriptor-O_RDWR-to-work-.patch ADDED
@@ -0,0 +1,68 @@
1
+ From 9452583824b50cb6f095c5ec1894b38df7b01175 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <9452583824b50cb6f095c5ec1894b38df7b01175.1464449390.git.jen@redhat.com>
3
+ In-Reply-To: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
4
+ References: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
5
+ From: Kevin Wolf <kwolf@redhat.com>
6
+ Date: Mon, 23 May 2016 11:28:41 -0400
7
+ Subject: [CHANGE 3/3] block/raw-posix: Open file descriptor O_RDWR to work
8
+ around glibc posix_fallocate emulation issue.
9
+ To: rhvirt-patches@redhat.com,
10
+ jen@redhat.com
11
+
12
+ RH-Author: Kevin Wolf <kwolf@redhat.com>
13
+ Message-id: <1464002921-1079-2-git-send-email-kwolf@redhat.com>
14
+ Patchwork-id: 70425
15
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] block/raw-posix: Open file descriptor O_RDWR to work around glibc posix_fallocate emulation issue.
16
+ Bugzilla: 1268345
17
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
18
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
19
+ RH-Acked-by: Richard Jones <rjones@redhat.com>
20
+
21
+ From: "Richard W.M. Jones" <rjones@redhat.com>
22
+
23
+ The following command fails on an NFS mountpoint:
24
+
25
+ $ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
26
+ Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
27
+ qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor
28
+
29
+ The reason turns out to be because NFS doesn't support the
30
+ posix_fallocate call. glibc emulates it instead. However glibc's
31
+ emulation involves using the pread(2) syscall. The pread syscall
32
+ fails with EBADF if the file descriptor is opened without the read
33
+ open-flag (ie. open (..., O_WRONLY)).
34
+
35
+ I contacted glibc upstream about this, and their response is here:
36
+
37
+ https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9
38
+
39
+ There are two possible fixes: Use Linux fallocate directly, or (this
40
+ fix) work around the problem in qemu by opening the file with O_RDWR
41
+ instead of O_WRONLY.
42
+
43
+ Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
44
+ Reviewed-by: Jeff Cody <jcody@redhat.com>
45
+ Reviewed-by: Eric Blake <eblake@redhat.com>
46
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
47
+ (cherry picked from commit 73ba05d936e82fe01b2b2cf987bf3aecb4792af5)
48
+ Signed-off-by: Jeff E. Nelson <jen@redhat.com>
49
+ ---
50
+ block/raw-posix.c | 2 +-
51
+ 1 file changed, 1 insertion(+), 1 deletion(-)
52
+
53
+ diff --git a/block/raw-posix.c b/block/raw-posix.c
54
+ index 1f5275f..92fcb6c 100644
55
+ --- a/block/raw-posix.c
56
+ +++ b/block/raw-posix.c
57
+ @@ -1265,7 +1265,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
58
+ options++;
59
+ }
60
+
61
+ - fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
62
+ + fd = qemu_open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
63
+ 0644);
64
+ if (fd < 0) {
65
+ result = -errno;
66
+ --
67
+ 2.5.5
68
+
SOURCES/kvm-block-vmdk-fixed-sizeof-error.patch ADDED
@@ -0,0 +1,50 @@
1
+ From 37bf9db781d9507501649ee04d23b0dab103a126 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:23 +0100
4
+ Subject: [PATCH 10/18] block: vmdk - fixed sizeof() error
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-11-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69176
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 10/18] block: vmdk - fixed sizeof() error
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ From: Jeff Cody <jcody@redhat.com>
16
+
17
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
18
+
19
+ The size compared should be PATH_MAX, rather than sizeof(char *).
20
+
21
+ Reported-by: Paolo Bonzini <pbonzini@redhat.com>
22
+ Signed-off-by: Jeff Cody <jcody@redhat.com>
23
+ Reviewed-by: Eric Blake <eblake@redhat.com>
24
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
25
+ Message-id: 46d873261433f4527e88885582f96942d61758d6.1423592487.git.jcody@redhat.com
26
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
27
+ (cherry picked from commit a7be17bee855f26c317e99aa6582e1dc9b8ebd71)
28
+ Signed-off-by: Fam Zheng <famz@redhat.com>
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ block/vmdk.c | 3 +--
32
+ 1 file changed, 1 insertion(+), 2 deletions(-)
33
+
34
+ diff --git a/block/vmdk.c b/block/vmdk.c
35
+ index 45ecf02..32b3d4c 100644
36
+ --- a/block/vmdk.c
37
+ +++ b/block/vmdk.c
38
+ @@ -838,8 +838,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
39
+ }
40
+
41
+ extent_path = g_malloc0(PATH_MAX);
42
+ - path_combine(extent_path, sizeof(extent_path),
43
+ - desc_file_path, fname);
44
+ + path_combine(extent_path, PATH_MAX, desc_file_path, fname);
45
+ extent_file = NULL;
46
+ ret = bdrv_file_open(&extent_file, extent_path, NULL, bs->open_flags,
47
+ errp);
48
+ --
49
+ 1.8.3.1
50
+
SOURCES/kvm-block-vmdk-make-ret-variable-usage-clear.patch ADDED
@@ -0,0 +1,86 @@
1
+ From 931d28d0c1c1015df16fbffb8422895497193a78 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:21 +0100
4
+ Subject: [PATCH 08/18] block: vmdk - make ret variable usage clear
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-9-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69174
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 08/18] block: vmdk - make ret variable usage clear
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ From: Jeff Cody <jcody@redhat.com>
16
+
17
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
18
+
19
+ Keep the variable 'ret' something that is returned by the function it is
20
+ defined in. For the return value of 'sscanf', use a more meaningful
21
+ variable name.
22
+
23
+ Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ Reviewed-by: John Snow <jsnow@redhat.com>
25
+ Signed-off-by: Jeff Cody <jcody@redhat.com>
26
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
+ (cherry picked from commit 395a22fae064df64d987d703cf70ae0f57306be8)
28
+ Signed-off-by: Fam Zheng <famz@redhat.com>
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ block/vmdk.c | 14 ++++++++------
32
+ 1 file changed, 8 insertions(+), 6 deletions(-)
33
+
34
+ diff --git a/block/vmdk.c b/block/vmdk.c
35
+ index 1247ea4..3351782 100644
36
+ --- a/block/vmdk.c
37
+ +++ b/block/vmdk.c
38
+ @@ -788,6 +788,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
39
+ const char *desc_file_path, Error **errp)
40
+ {
41
+ int ret;
42
+ + int matches;
43
+ char access[11];
44
+ char type[11];
45
+ char fname[512];
46
+ @@ -799,6 +800,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
47
+ BDRVVmdkState *s = bs->opaque;
48
+ VmdkExtent *extent;
49
+
50
+ +
51
+ while (*p) {
52
+ /* parse extent line in one of below formats:
53
+ *
54
+ @@ -808,23 +810,23 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
55
+ * RW [size in sectors] VMFSSPARSE "file-name.vmdk"
56
+ */
57
+ flat_offset = -1;
58
+ - ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
59
+ - access, &sectors, type, fname, &flat_offset);
60
+ - if (ret < 4 || strcmp(access, "RW")) {
61
+ + matches = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
62
+ + access, &sectors, type, fname, &flat_offset);
63
+ + if (matches < 4 || strcmp(access, "RW")) {
64
+ goto next_line;
65
+ } else if (!strcmp(type, "FLAT")) {
66
+ - if (ret != 5 || flat_offset < 0) {
67
+ + if (matches != 5 || flat_offset < 0) {
68
+ error_setg(errp, "Invalid extent lines: \n%s", p);
69
+ return -EINVAL;
70
+ }
71
+ } else if (!strcmp(type, "VMFS")) {
72
+ - if (ret == 4) {
73
+ + if (matches == 4) {
74
+ flat_offset = 0;
75
+ } else {
76
+ error_setg(errp, "Invalid extent lines:\n%s", p);
77
+ return -EINVAL;
78
+ }
79
+ - } else if (ret != 4) {
80
+ + } else if (matches != 4) {
81
+ error_setg(errp, "Invalid extent lines:\n%s", p);
82
+ return -EINVAL;
83
+ }
84
+ --
85
+ 1.8.3.1
86
+
SOURCES/kvm-block-vmdk-move-string-allocations-from-stack-to-the.patch ADDED
@@ -0,0 +1,146 @@
1
+ From a767838caf6c761d714a9466d008f8dddaf1a162 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:22 +0100
4
+ Subject: [PATCH 09/18] block: vmdk - move string allocations from stack to the
5
+ heap
6
+
7
+ RH-Author: Fam Zheng <famz@redhat.com>
8
+ Message-id: <1455528511-9357-10-git-send-email-famz@redhat.com>
9
+ Patchwork-id: 69175
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 09/18] block: vmdk - move string allocations from stack to the heap
11
+ Bugzilla: 1299250
12
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
15
+
16
+ From: Jeff Cody <jcody@redhat.com>
17
+
18
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
19
+
20
+ Functions 'vmdk_parse_extents' and 'vmdk_create' allocate several
21
+ PATH_MAX sized arrays on the stack. Make these dynamically allocated.
22
+
23
+ Signed-off-by: Jeff Cody <jcody@redhat.com>
24
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
+ (cherry picked from commit fe2065629a9c256f836770ca54449ae77b22d188)
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+ ---
29
+ block/vmdk.c | 40 ++++++++++++++++++++++++----------------
30
+ 1 file changed, 24 insertions(+), 16 deletions(-)
31
+
32
+ diff --git a/block/vmdk.c b/block/vmdk.c
33
+ index 3351782..45ecf02 100644
34
+ --- a/block/vmdk.c
35
+ +++ b/block/vmdk.c
36
+ @@ -795,12 +795,11 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
37
+ const char *p = desc;
38
+ int64_t sectors = 0;
39
+ int64_t flat_offset;
40
+ - char extent_path[PATH_MAX];
41
+ + char *extent_path;
42
+ BlockDriverState *extent_file;
43
+ BDRVVmdkState *s = bs->opaque;
44
+ VmdkExtent *extent;
45
+
46
+ -
47
+ while (*p) {
48
+ /* parse extent line in one of below formats:
49
+ *
50
+ @@ -838,10 +837,13 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
51
+ goto next_line;
52
+ }
53
+
54
+ + extent_path = g_malloc0(PATH_MAX);
55
+ path_combine(extent_path, sizeof(extent_path),
56
+ desc_file_path, fname);
57
+ + extent_file = NULL;
58
+ ret = bdrv_file_open(&extent_file, extent_path, NULL, bs->open_flags,
59
+ errp);
60
+ + g_free(extent_path);
61
+ if (ret) {
62
+ return ret;
63
+ }
64
+ @@ -1790,10 +1792,15 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
65
+ int ret = 0;
66
+ bool flat, split, compress;
67
+ GString *ext_desc_lines;
68
+ - char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
69
+ + char *path = g_malloc0(PATH_MAX);
70
+ + char *prefix = g_malloc0(PATH_MAX);
71
+ + char *postfix = g_malloc0(PATH_MAX);
72
+ + char *desc_line = g_malloc0(BUF_SIZE);
73
+ + char *ext_filename = g_malloc0(PATH_MAX);
74
+ + char *desc_filename = g_malloc0(PATH_MAX);
75
+ const int64_t split_size = 0x80000000; /* VMDK has constant split size */
76
+ const char *desc_extent_line;
77
+ - char parent_desc_line[BUF_SIZE] = "";
78
+ + char *parent_desc_line = g_malloc0(BUF_SIZE);
79
+ uint32_t parent_cid = 0xffffffff;
80
+ uint32_t number_heads = 16;
81
+ bool zeroed_grain = false;
82
+ @@ -1902,33 +1909,27 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
83
+ }
84
+ parent_cid = vmdk_read_cid(bs, 0);
85
+ bdrv_unref(bs);
86
+ - snprintf(parent_desc_line, sizeof(parent_desc_line),
87
+ + snprintf(parent_desc_line, BUF_SIZE,
88
+ "parentFileNameHint=\"%s\"", backing_file);
89
+ }
90
+
91
+ /* Create extents */
92
+ filesize = total_size;
93
+ while (filesize > 0) {
94
+ - char desc_line[BUF_SIZE];
95
+ - char ext_filename[PATH_MAX];
96
+ - char desc_filename[PATH_MAX];
97
+ int64_t size = filesize;
98
+
99
+ if (split && size > split_size) {
100
+ size = split_size;
101
+ }
102
+ if (split) {
103
+ - snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
104
+ + snprintf(desc_filename, PATH_MAX, "%s-%c%03d%s",
105
+ prefix, flat ? 'f' : 's', ++idx, postfix);
106
+ } else if (flat) {
107
+ - snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
108
+ - prefix, postfix);
109
+ + snprintf(desc_filename, PATH_MAX, "%s-flat%s", prefix, postfix);
110
+ } else {
111
+ - snprintf(desc_filename, sizeof(desc_filename), "%s%s",
112
+ - prefix, postfix);
113
+ + snprintf(desc_filename, PATH_MAX, "%s%s", prefix, postfix);
114
+ }
115
+ - snprintf(ext_filename, sizeof(ext_filename), "%s%s",
116
+ - path, desc_filename);
117
+ + snprintf(ext_filename, PATH_MAX, "%s%s", path, desc_filename);
118
+
119
+ if (vmdk_create_extent(ext_filename, size,
120
+ flat, compress, zeroed_grain, errp)) {
121
+ @@ -1938,7 +1939,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
122
+ filesize -= size;
123
+
124
+ /* Format description line */
125
+ - snprintf(desc_line, sizeof(desc_line),
126
+ + snprintf(desc_line, BUF_SIZE,
127
+ desc_extent_line, size / BDRV_SECTOR_SIZE, desc_filename);
128
+ g_string_append(ext_desc_lines, desc_line);
129
+ }
130
+ @@ -1988,6 +1989,13 @@ exit:
131
+ bdrv_unref(new_bs);
132
+ }
133
+ g_free(desc);
134
+ + g_free(path);
135
+ + g_free(prefix);
136
+ + g_free(postfix);
137
+ + g_free(desc_line);
138
+ + g_free(ext_filename);
139
+ + g_free(desc_filename);
140
+ + g_free(parent_desc_line);
141
+ g_string_free(ext_desc_lines, true);
142
+ return ret;
143
+ }
144
+ --
145
+ 1.8.3.1
146
+
SOURCES/kvm-check-qjson-Add-test-for-JSON-nesting-depth-limit.patch ADDED
@@ -0,0 +1,73 @@
1
+ From 38d4fe12ad2e3bc18842201f437c480120eace2b Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:02 +0200
4
+ Subject: [PATCH 04/16] check-qjson: Add test for JSON nesting depth limit
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-6-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71481
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 04/15] check-qjson: Add test for JSON nesting depth limit
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ This would have prevented the regression mentioned in the previous
16
+ commit.
17
+
18
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
19
+ Reviewed-by: Eric Blake <eblake@redhat.com>
20
+ Message-Id: <1448486613-17634-4-git-send-email-armbru@redhat.com>
21
+ (cherry picked from commit f0ae0304c7a41a42b7d4a6cde450da938d3c2cc7)
22
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
23
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
24
+ ---
25
+ tests/check-qjson.c | 25 +++++++++++++++++++++++++
26
+ 1 file changed, 25 insertions(+)
27
+
28
+ diff --git a/tests/check-qjson.c b/tests/check-qjson.c
29
+ index 4e74548..c5dd74d 100644
30
+ --- a/tests/check-qjson.c
31
+ +++ b/tests/check-qjson.c
32
+ @@ -1465,6 +1465,30 @@ static void unterminated_literal(void)
33
+ g_assert(obj == NULL);
34
+ }
35
+
36
+ +static char *make_nest(char *buf, size_t cnt)
37
+ +{
38
+ + memset(buf, '[', cnt - 1);
39
+ + buf[cnt - 1] = '{';
40
+ + buf[cnt] = '}';
41
+ + memset(buf + cnt + 1, ']', cnt - 1);
42
+ + buf[2 * cnt] = 0;
43
+ + return buf;
44
+ +}
45
+ +
46
+ +static void limits_nesting(void)
47
+ +{
48
+ + enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
49
+ + char buf[2 * (max_nesting + 1) + 1];
50
+ + QObject *obj;
51
+ +
52
+ + obj = qobject_from_json(make_nest(buf, max_nesting));
53
+ + g_assert(obj != NULL);
54
+ + qobject_decref(obj);
55
+ +
56
+ + obj = qobject_from_json(make_nest(buf, max_nesting + 1));
57
+ + g_assert(obj == NULL);
58
+ +}
59
+ +
60
+ int main(int argc, char **argv)
61
+ {
62
+ g_test_init(&argc, &argv, NULL);
63
+ @@ -1500,6 +1524,7 @@ int main(int argc, char **argv)
64
+ g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
65
+ g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
66
+ g_test_add_func("/errors/unterminated/literal", unterminated_literal);
67
+ + g_test_add_func("/errors/limits/nesting", limits_nesting);
68
+
69
+ return g_test_run();
70
+ }
71
+ --
72
+ 1.8.3.1
73
+
SOURCES/kvm-cutils-Support-P-and-E-suffixes-in-strtosz.patch ADDED
@@ -0,0 +1,132 @@
1
+ From b7cea737b24456765a21ed43ebd9b68ebbbf3537 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:21 +0100
4
+ Subject: [PATCH 02/27] cutils: Support 'P' and 'E' suffixes in strtosz()
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-3-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68430
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 02/21] cutils: Support 'P' and 'E' suffixes in strtosz()
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
+ Reviewed-by: Eric Blake <eblake@redhat.com>
19
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
+ (cherry picked from commit 5e00984aef7c1c317e27c0e8acf66526513c770f)
21
+ Signed-off-by: John Snow <jsnow@redhat.com>
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+ ---
24
+ include/qemu-common.h | 2 ++
25
+ monitor.c | 8 ++++----
26
+ qemu-img.c | 10 ++++++----
27
+ tests/qemu-iotests/049.out | 8 ++++----
28
+ util/cutils.c | 4 ++++
29
+ 5 files changed, 20 insertions(+), 12 deletions(-)
30
+
31
+ diff --git a/include/qemu-common.h b/include/qemu-common.h
32
+ index aee85e3..67f57c9 100644
33
+ --- a/include/qemu-common.h
34
+ +++ b/include/qemu-common.h
35
+ @@ -178,6 +178,8 @@ int parse_uint_full(const char *s, unsigned long long *value, int base);
36
+ * A-Z, as strtosz() will use qemu_toupper() on the given argument
37
+ * prior to comparison.
38
+ */
39
+ +#define STRTOSZ_DEFSUFFIX_EB 'E'
40
+ +#define STRTOSZ_DEFSUFFIX_PB 'P'
41
+ #define STRTOSZ_DEFSUFFIX_TB 'T'
42
+ #define STRTOSZ_DEFSUFFIX_GB 'G'
43
+ #define STRTOSZ_DEFSUFFIX_MB 'M'
44
+ diff --git a/monitor.c b/monitor.c
45
+ index 6a1d06e..33c5bc8 100644
46
+ --- a/monitor.c
47
+ +++ b/monitor.c
48
+ @@ -94,10 +94,10 @@
49
+ * 'M' Non-negative target long (32 or 64 bit), in user mode the
50
+ * value is multiplied by 2^20 (think Mebibyte)
51
+ * 'o' octets (aka bytes)
52
+ - * user mode accepts an optional T, t, G, g, M, m, K, k
53
+ - * suffix, which multiplies the value by 2^40 for
54
+ - * suffixes T and t, 2^30 for suffixes G and g, 2^20 for
55
+ - * M and m, 2^10 for K and k
56
+ + * user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
57
+ + * K, k suffix, which multiplies the value by 2^60 for suffixes E
58
+ + * and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
59
+ + * 2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
60
+ * 'T' double
61
+ * user mode accepts an optional ms, us, ns suffix,
62
+ * which divides the value by 1e3, 1e6, 1e9, respectively
63
+ diff --git a/qemu-img.c b/qemu-img.c
64
+ index 9c021e7..eb2d4cb 100644
65
+ --- a/qemu-img.c
66
+ +++ b/qemu-img.c
67
+ @@ -87,8 +87,9 @@ static void help(void)
68
+ " 'src_cache' is the cache mode used to read input disk images, the valid\n"
69
+ " options are the same as for the 'cache' option\n"
70
+ " 'size' is the disk image size in bytes. Optional suffixes\n"
71
+ - " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
72
+ - " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
73
+ + " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M),\n"
74
+ + " 'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P) are\n"
75
+ + " supported. 'b' is ignored.\n"
76
+ " 'output_filename' is the destination disk image filename\n"
77
+ " 'output_fmt' is the destination format\n"
78
+ " 'options' is a comma separated list of format specific options in a\n"
79
+ @@ -417,8 +418,9 @@ static int img_create(int argc, char **argv)
80
+ error_report("Image size must be less than 8 EiB!");
81
+ } else {
82
+ error_report("Invalid image size specified! You may use k, M, "
83
+ - "G or T suffixes for ");
84
+ - error_report("kilobytes, megabytes, gigabytes and terabytes.");
85
+ + "G, T, P or E suffixes for ");
86
+ + error_report("kilobytes, megabytes, gigabytes, terabytes, "
87
+ + "petabytes and exabytes.");
88
+ }
89
+ goto fail;
90
+ }
91
+ diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
92
+ index b2fcf0b..3e56772 100644
93
+ --- a/tests/qemu-iotests/049.out
94
+ +++ b/tests/qemu-iotests/049.out
95
+ @@ -108,15 +108,15 @@ qemu-img: TEST_DIR/t.qcow2: Could not resize image: Operation not supported
96
+ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off cluster_size=65536 lazy_refcounts=off
97
+
98
+ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
99
+ -qemu-img: Invalid image size specified! You may use k, M, G or T suffixes for
100
+ -qemu-img: kilobytes, megabytes, gigabytes and terabytes.
101
+ +qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
102
+ +qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
103
+
104
+ qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2
105
+ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
106
+
107
+ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar
108
+ -qemu-img: Invalid image size specified! You may use k, M, G or T suffixes for
109
+ -qemu-img: kilobytes, megabytes, gigabytes and terabytes.
110
+ +qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
111
+ +qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
112
+
113
+ qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
114
+ qemu-img: Parameter 'size' expects a size
115
+ diff --git a/util/cutils.c b/util/cutils.c
116
+ index a165819..8f28896 100644
117
+ --- a/util/cutils.c
118
+ +++ b/util/cutils.c
119
+ @@ -267,6 +267,10 @@ static int64_t suffix_mul(char suffix, int64_t unit)
120
+ return unit * unit * unit;
121
+ case STRTOSZ_DEFSUFFIX_TB:
122
+ return unit * unit * unit * unit;
123
+ + case STRTOSZ_DEFSUFFIX_PB:
124
+ + return unit * unit * unit * unit * unit;
125
+ + case STRTOSZ_DEFSUFFIX_EB:
126
+ + return unit * unit * unit * unit * unit * unit;
127
+ }
128
+ return -1;
129
+ }
130
+ --
131
+ 1.8.3.1
132
+
SOURCES/kvm-e1000-eliminate-infinite-loops-on-out-of-bounds-tran.patch ADDED
@@ -0,0 +1,109 @@
1
+ From 4fef3479339001ef3ea529fb0552533fae422240 Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Fri, 5 Feb 2016 14:26:18 +0100
4
+ Subject: [PATCH 1/5] e1000: eliminate infinite loops on out-of-bounds transfer
5
+ start
6
+
7
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
8
+ Message-id: <1454682378-29144-2-git-send-email-lersek@redhat.com>
9
+ Patchwork-id: 69116
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] e1000: eliminate infinite loops on out-of-bounds transfer start
11
+ Bugzilla: 1296044
12
+ RH-Acked-by: Xiao Wang <jasowang@redhat.com>
13
+ RH-Acked-by: P J P <ppandit@redhat.com>
14
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
15
+
16
+ The start_xmit() and e1000_receive_iov() functions implement DMA transfers
17
+ iterating over a set of descriptors that the guest's e1000 driver
18
+ prepares:
19
+
20
+ - the TDLEN and RDLEN registers store the total size of the descriptor
21
+ area,
22
+
23
+ - while the TDH and RDH registers store the offset (in whole tx / rx
24
+ descriptors) into the area where the transfer is supposed to start.
25
+
26
+ Each time a descriptor is processed, the TDH and RDH register is bumped
27
+ (as appropriate for the transfer direction).
28
+
29
+ QEMU already contains logic to deal with bogus transfers submitted by the
30
+ guest:
31
+
32
+ - Normally, the transmit case wants to increase TDH from its initial value
33
+ to TDT. (TDT is allowed to be numerically smaller than the initial TDH
34
+ value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
35
+ that QEMU currently has here is a check against reaching the original
36
+ TDH value again -- a complete wraparound, which should never happen.
37
+
38
+ - In the receive case RDH is increased from its initial value until
39
+ "total_size" bytes have been received; preferably in a single step, or
40
+ in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
41
+ RX descriptors are skipped without receiving data, while RDH is
42
+ incremented just the same. QEMU tries to prevent an infinite loop
43
+ (processing only null RX descriptors) by detecting whether RDH assumes
44
+ its original value during the loop. (Again, wrapping from RDLEN to 0 is
45
+ normal.)
46
+
47
+ What both directions miss is that the guest could program TDLEN and RDLEN
48
+ so low, and the initial TDH and RDH so high, that these registers will
49
+ immediately be truncated to zero, and then never reassume their initial
50
+ values in the loop -- a full wraparound will never occur.
51
+
52
+ The condition that expresses this is:
53
+
54
+ xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)
55
+
56
+ i.e., TDH or RDH start out after the last whole rx or tx descriptor that
57
+ fits into the TDLEN or RDLEN sized area.
58
+
59
+ This condition could be checked before we enter the loops, but
60
+ pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
61
+ bogus DMA addresses, so we just extend the existing failsafes with the
62
+ above condition.
63
+
64
+ This is CVE-2016-1981.
65
+
66
+ Cc: "Michael S. Tsirkin" <mst@redhat.com>
67
+ Cc: Petr Matousek <pmatouse@redhat.com>
68
+ Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
69
+ Cc: Prasad Pandit <ppandit@redhat.com>
70
+ Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
71
+ Cc: Jason Wang <jasowang@redhat.com>
72
+ Cc: qemu-stable@nongnu.org
73
+ RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
74
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
75
+ Reviewed-by: Jason Wang <jasowang@redhat.com>
76
+ Signed-off-by: Jason Wang <jasowang@redhat.com>
77
+ (cherry picked from commit dd793a74882477ca38d49e191110c17dfee51dcc)
78
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
79
+ ---
80
+ hw/net/e1000.c | 6 ++++--
81
+ 1 file changed, 4 insertions(+), 2 deletions(-)
82
+
83
+ diff --git a/hw/net/e1000.c b/hw/net/e1000.c
84
+ index 87a84a7..2cd38bc 100644
85
+ --- a/hw/net/e1000.c
86
+ +++ b/hw/net/e1000.c
87
+ @@ -697,7 +697,8 @@ start_xmit(E1000State *s)
88
+ * bogus values to TDT/TDLEN.
89
+ * there's nothing too intelligent we could do about this.
90
+ */
91
+ - if (s->mac_reg[TDH] == tdh_start) {
92
+ + if (s->mac_reg[TDH] == tdh_start ||
93
+ + tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
94
+ DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
95
+ tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
96
+ break;
97
+ @@ -902,7 +903,8 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
98
+ if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
99
+ s->mac_reg[RDH] = 0;
100
+ /* see comment in start_xmit; same here */
101
+ - if (s->mac_reg[RDH] == rdh_start) {
102
+ + if (s->mac_reg[RDH] == rdh_start ||
103
+ + rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
104
+ DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
105
+ rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
106
+ set_ics(s, 0, E1000_ICS_RXO);
107
+ --
108
+ 1.8.3.1
109
+
SOURCES/kvm-ehci-clear-suspend-bit-on-detach.patch ADDED
@@ -0,0 +1,48 @@
1
+ From ad3f6b5b188c572bd07cc5929e844138c2d95915 Mon Sep 17 00:00:00 2001
2
+ From: Gerd Hoffmann <kraxel@redhat.com>
3
+ Date: Fri, 13 Nov 2015 13:32:34 +0100
4
+ Subject: [PATCH 1/6] ehci: clear suspend bit on detach
5
+
6
+ Message-id: <1447421554-28366-2-git-send-email-kraxel@redhat.com>
7
+ Patchwork-id: 68349
8
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] ehci: clear suspend bit on detach
9
+ Bugzilla: 1268879
10
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
11
+ RH-Acked-by: John Snow <jsnow@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+
14
+ When a device is detached, clear the suspend bit (PORTSC_SUSPEND)
15
+ in the port status register.
16
+
17
+ The specs are not *that* clear what is supposed to happen in case
18
+ a suspended device is unplugged. But the enable bit (PORTSC_PED)
19
+ is cleared, and the specs mention setting suspend with enable being
20
+ unset is undefined behavior. So clearing them both looks reasonable,
21
+ and it actually fixes the reported bug.
22
+
23
+ Cc: Hans de Goede <hdegoede@redhat.com>
24
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
25
+ Reviewed-by: Hans de Goede <hdegoede@redhat.com>
26
+ Message-id: 1445413462-18004-1-git-send-email-kraxel@redhat.com
27
+ (cherry picked from commit cbf82fa01e6fd4ecb234b235b10ffce548154a95)
28
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
29
+ ---
30
+ hw/usb/hcd-ehci.c | 2 +-
31
+ 1 file changed, 1 insertion(+), 1 deletion(-)
32
+
33
+ diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
34
+ index 02d2ab7..3429c77 100644
35
+ --- a/hw/usb/hcd-ehci.c
36
+ +++ b/hw/usb/hcd-ehci.c
37
+ @@ -802,7 +802,7 @@ static void ehci_detach(USBPort *port)
38
+ ehci_queues_rip_device(s, port->dev, 0);
39
+ ehci_queues_rip_device(s, port->dev, 1);
40
+
41
+ - *portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
42
+ + *portsc &= ~(PORTSC_CONNECT|PORTSC_PED|PORTSC_SUSPEND);
43
+ *portsc |= PORTSC_CSC;
44
+
45
+ ehci_raise_irq(s, USBSTS_PCD);
46
+ --
47
+ 1.8.3.1
48
+
SOURCES/kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch CHANGED
@@ -1,16 +1,17 @@
1
- From 5d12c17191e042a57e02749cedc55104a8251ac3 Mon Sep 17 00:00:00 2001
1
+ From ba24567fd90702ea40ff320a79bc921b38510f22 Mon Sep 17 00:00:00 2001
2
2
From: Miroslav Rezanina <mrezanin@redhat.com>
3
3
Date: Thu, 21 Jan 2016 07:17:43 +0100
4
- Subject: [PATCH] fw_cfg: add check to validate current entry value
4
+ Subject: [PATCH 2/2] fw_cfg: add check to validate current entry value
5
5
(CVE-2016-1714)
6
6
MIME-Version: 1.0
7
7
Content-Type: text/plain; charset=UTF-8
8
8
Content-Transfer-Encoding: 8bit
9
9
10
+ RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
10
11
Message-id: <1453360663-5066-1-git-send-email-mrezanin@redhat.com>
11
12
Patchwork-id: 68834
12
13
O-Subject: [RHEL-7.2.z/RHEL-7.3 qemu-kvm PATCH] fw_cfg: add check to validate current entry value (CVE-2016-1714)
13
- Bugzilla: 1298047
14
+ Bugzilla: 1298048
14
15
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
15
16
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
16
17
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
SOURCES/kvm-hw-input-hid.c-Fix-capslock-hid-code.patch ADDED
@@ -0,0 +1,50 @@
1
+ From 61ecb3c995018bc9ec901d376004c1d092d166ff Mon Sep 17 00:00:00 2001
2
+ From: Gerd Hoffmann <kraxel@redhat.com>
3
+ Date: Wed, 1 Jun 2016 12:24:01 +0200
4
+ Subject: [PATCH 1/3] hw/input/hid.c Fix capslock hid code
5
+
6
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
+ Message-id: <1464783841-27701-2-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 70522
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] hw/input/hid.c Fix capslock hid code
10
+ Bugzilla: 1256741
11
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
12
+ RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
13
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
14
+
15
+ From: Dinar Valeev <dvaleev@suse.com>
16
+
17
+ When ever USB keyboard is used, e.g. '-usbdevice keyboard' pressing
18
+ caps lock key send 0x32 hid code, which is treated as backslash.
19
+ Instead it should be 0x39 code. This affects sending uppercase keys,
20
+ as they typed whith caps lock active.
21
+
22
+ While on x86 this can be workarounded by using ps/2 protocol. On
23
+ Power it is crusial as we don't have anything else than USB.
24
+
25
+ This is fixes guest automation tasts over vnc.
26
+
27
+ Signed-off-by: Dinar Valeev <dvaleev@suse.com>
28
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
29
+ (cherry picked from commit 0ee4de5840ccc1072459ec68062bfb63c888a94d)
30
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
31
+ ---
32
+ hw/input/hid.c | 2 +-
33
+ 1 file changed, 1 insertion(+), 1 deletion(-)
34
+
35
+ diff --git a/hw/input/hid.c b/hw/input/hid.c
36
+ index 14b3125..db45c89 100644
37
+ --- a/hw/input/hid.c
38
+ +++ b/hw/input/hid.c
39
+ @@ -41,7 +41,7 @@ static const uint8_t hid_usage_keys[0x100] = {
40
+ 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
41
+ 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
42
+ 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
43
+ - 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
44
+ + 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
45
+ 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
46
+ 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
47
+ 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
48
+ --
49
+ 1.8.3.1
50
+
SOURCES/kvm-ide-test-fix-failure-for-test_flush.patch ADDED
@@ -0,0 +1,113 @@
1
+ From 31ce74359a069be69af0f6ba2f7867ed2083317a Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Tue, 8 Dec 2015 20:30:59 +0100
4
+ Subject: [PATCH 21/27] ide-test: fix failure for test_flush
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1449606659-23710-1-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68521
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v3 21/21] ide-test: fix failure for test_flush
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ This patch is a combination of two patches:
16
+
17
+ (1) Revert "qtest/ide-test: disable flush-test"
18
+ (2) ide-test: fix failure for test_flush
19
+
20
+ First, the downstream-only revert:
21
+ This reverts commit 228e49fabffa644ab7a6a03e98205f293115dc89.
22
+
23
+ Second, the backported fix:
24
+
25
+ bd07684aacfb61668ae2c25b7dd00b64f3d7c7f3 added a test to ensure BSY
26
+ flag is set when a flush request is in flight. It does this by setting
27
+ a blkdebug breakpoint on flush_to_os before issuing a CMD_FLUSH_CACHE.
28
+ It then resumes CMD_FLUSH_CACHE operation and checks that BSY is unset.
29
+
30
+ The actual unsetting of BSY does not occur until ide_flush_cb gets
31
+ called in a bh, however, so in some cases this check will race with
32
+ the actual completion.
33
+
34
+ Fix this by polling the ide status register until BSY flag gets unset
35
+ before we do our final sanity checks. According to
36
+ f68ec8379e88502b4841a110c070e9b118d3151c this is in line with how a guest
37
+ would determine whether or not the device is still busy.
38
+
39
+ Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
40
+ Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
41
+ (cherry picked from commit 22bfa16ed3d4c9d534dcfe6f2381a654f32296b9)
42
+ Signed-off-by: John Snow <jsnow@redhat.com>
43
+ ---
44
+ tests/ide-test.c | 41 +++++++++++++++++++++++++++++++++++++++++
45
+ 1 file changed, 41 insertions(+)
46
+
47
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
48
+ ---
49
+ tests/ide-test.c | 41 +++++++++++++++++++++++++++++++++++++++++
50
+ 1 file changed, 41 insertions(+)
51
+
52
+ diff --git a/tests/ide-test.c b/tests/ide-test.c
53
+ index 43b7fd6..92dd0e5 100644
54
+ --- a/tests/ide-test.c
55
+ +++ b/tests/ide-test.c
56
+ @@ -425,6 +425,46 @@ static void test_identify(void)
57
+ ide_test_quit();
58
+ }
59
+
60
+ +static void test_flush(void)
61
+ +{
62
+ + uint8_t data;
63
+ +
64
+ + ide_test_start(
65
+ + "-vnc none "
66
+ + "-drive file=blkdebug::%s,if=ide,cache=writeback",
67
+ + tmp_path);
68
+ +
69
+ + /* Delay the completion of the flush request until we explicitly do it */
70
+ + qmp("{'execute':'human-monitor-command', 'arguments': { "
71
+ + "'command-line': 'qemu-io ide0-hd0 \"break flush_to_os A\"'} }");
72
+ +
73
+ + /* FLUSH CACHE command on device 0*/
74
+ + outb(IDE_BASE + reg_device, 0);
75
+ + outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
76
+ +
77
+ + /* Check status while request is in flight*/
78
+ + data = inb(IDE_BASE + reg_status);
79
+ + assert_bit_set(data, BSY | DRDY);
80
+ + assert_bit_clear(data, DF | ERR | DRQ);
81
+ +
82
+ + /* Complete the command */
83
+ + qmp("{'execute':'human-monitor-command', 'arguments': { "
84
+ + "'command-line': 'qemu-io ide0-hd0 \"resume A\"'} }");
85
+ +
86
+ + /* Check registers */
87
+ + data = inb(IDE_BASE + reg_device);
88
+ + g_assert_cmpint(data & DEV, ==, 0);
89
+ +
90
+ + do {
91
+ + data = inb(IDE_BASE + reg_status);
92
+ + } while (data & BSY);
93
+ +
94
+ + assert_bit_set(data, DRDY);
95
+ + assert_bit_clear(data, BSY | DF | ERR | DRQ);
96
+ +
97
+ + ide_test_quit();
98
+ +}
99
+ +
100
+ static void test_flush_nodev(void)
101
+ {
102
+ ide_test_start("");
103
+ @@ -468,6 +508,7 @@ int main(int argc, char **argv)
104
+ qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt);
105
+ qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown);
106
+
107
+ + qtest_add_func("/ide/flush", test_flush);
108
+ qtest_add_func("/ide/flush_nodev", test_flush_nodev);
109
+
110
+ ret = g_test_run();
111
+ --
112
+ 1.8.3.1
113
+
SOURCES/kvm-json-parser-drop-superfluous-assignment-for-token-va.patch ADDED
@@ -0,0 +1,97 @@
1
+ From 110f5902133db4e8a46c9cc18ed0d4ed2e99aec2 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:34:59 +0200
4
+ Subject: [PATCH 01/16] json-parser: drop superfluous assignment for token
5
+ variable
6
+
7
+ RH-Author: Markus Armbruster <armbru@redhat.com>
8
+ Message-id: <1469604913-12442-3-git-send-email-armbru@redhat.com>
9
+ Patchwork-id: 71470
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 01/15] json-parser: drop superfluous assignment for token variable
11
+ Bugzilla: 1276036
12
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
13
+ RH-Acked-by: John Snow <jsnow@redhat.com>
14
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
15
+
16
+ From: Gonglei <arei.gonglei@huawei.com>
17
+
18
+ Signed-off-by: ChenLiang <chenliang88@huawei.com>
19
+ Signed-off-by: Gonglei <arei.gonglei@huawei.com>
20
+ Reviewed-by: Eric Blake <eblake@redhat.com>
21
+ Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
22
+ Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
23
+ (cherry picked from commit a491af471bf8f1188b2665f54d109065d4591e45)
24
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ qobject/json-parser.c | 15 ++-------------
28
+ 1 file changed, 2 insertions(+), 13 deletions(-)
29
+
30
+ diff --git a/qobject/json-parser.c b/qobject/json-parser.c
31
+ index e7947b3..fa09769 100644
32
+ --- a/qobject/json-parser.c
33
+ +++ b/qobject/json-parser.c
34
+ @@ -423,7 +423,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
35
+ if (!token_is_operator(token, '{')) {
36
+ goto out;
37
+ }
38
+ - token = NULL;
39
+
40
+ dict = qdict_new();
41
+
42
+ @@ -449,7 +448,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
43
+ parse_error(ctxt, token, "expected separator in dict");
44
+ goto out;
45
+ }
46
+ - token = NULL;
47
+
48
+ if (parse_pair(ctxt, dict, ap) == -1) {
49
+ goto out;
50
+ @@ -461,10 +459,8 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
51
+ goto out;
52
+ }
53
+ }
54
+ - token = NULL;
55
+ } else {
56
+ - token = parser_context_pop_token(ctxt);
57
+ - token = NULL;
58
+ + (void)parser_context_pop_token(ctxt);
59
+ }
60
+
61
+ return QOBJECT(dict);
62
+ @@ -487,10 +483,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
63
+ }
64
+
65
+ if (!token_is_operator(token, '[')) {
66
+ - token = NULL;
67
+ goto out;
68
+ }
69
+ - token = NULL;
70
+
71
+ list = qlist_new();
72
+
73
+ @@ -523,8 +517,6 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
74
+ goto out;
75
+ }
76
+
77
+ - token = NULL;
78
+ -
79
+ obj = parse_value(ctxt, ap);
80
+ if (obj == NULL) {
81
+ parse_error(ctxt, token, "expecting value");
82
+ @@ -539,11 +531,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
83
+ goto out;
84
+ }
85
+ }
86
+ -
87
+ - token = NULL;
88
+ } else {
89
+ - token = parser_context_pop_token(ctxt);
90
+ - token = NULL;
91
+ + (void)parser_context_pop_token(ctxt);
92
+ }
93
+
94
+ return QOBJECT(list);
95
+ --
96
+ 1.8.3.1
97
+
SOURCES/kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch ADDED
@@ -0,0 +1,65 @@
1
+ From b3e87d63aec8631b853cb86a0736af41954769a4 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:12 +0200
4
+ Subject: [PATCH 14/16] json-streamer: Don't leak tokens on incomplete parse
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-16-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71477
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 14/15] json-streamer: Don't leak tokens on incomplete parse
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Eric Blake <eblake@redhat.com>
16
+
17
+ Valgrind complained about a number of leaks in
18
+ tests/check-qobject-json:
19
+
20
+ ==12657== definitely lost: 17,247 bytes in 1,234 blocks
21
+
22
+ All of which had the same root cause: on an incomplete parse,
23
+ we were abandoning the token queue without cleaning up the
24
+ allocated data within each queue element. Introduced in
25
+ commit 95385fe, when we switched from QList (which recursively
26
+ frees contents) to g_queue (which does not).
27
+
28
+ We don't yet require glib 2.32 with its g_queue_free_full(),
29
+ so open-code it instead.
30
+
31
+ CC: qemu-stable@nongnu.org
32
+ Signed-off-by: Eric Blake <eblake@redhat.com>
33
+ Message-Id: <1463608012-12760-1-git-send-email-eblake@redhat.com>
34
+ Reviewed-by: Markus Armbruster <armbru@redhat.com>
35
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
36
+ (cherry picked from commit ba4dba54347d5062436a8553f527dbbed6dcf069)
37
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
38
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
39
+ ---
40
+ qobject/json-streamer.c | 6 ++++++
41
+ 1 file changed, 6 insertions(+)
42
+
43
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
44
+ index a4db4b8..3c7d6be 100644
45
+ --- a/qobject/json-streamer.c
46
+ +++ b/qobject/json-streamer.c
47
+ @@ -19,9 +19,15 @@
48
+ #define MAX_TOKEN_COUNT (2ULL << 20)
49
+ #define MAX_NESTING (1ULL << 10)
50
+
51
+ +static void json_message_free_token(void *token, void *opaque)
52
+ +{
53
+ + g_free(token);
54
+ +}
55
+ +
56
+ static void json_message_free_tokens(JSONMessageParser *parser)
57
+ {
58
+ if (parser->tokens) {
59
+ + g_queue_foreach(parser->tokens, json_message_free_token, NULL);
60
+ g_queue_free(parser->tokens);
61
+ parser->tokens = NULL;
62
+ }
63
+ --
64
+ 1.8.3.1
65
+
SOURCES/kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch ADDED
@@ -0,0 +1,64 @@
1
+ From a781053c1b5084ba32b86229b98b9601c990722c Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:13 +0200
4
+ Subject: [PATCH 15/16] json-streamer: fix double-free on exiting during a
5
+ parse
6
+
7
+ RH-Author: Markus Armbruster <armbru@redhat.com>
8
+ Message-id: <1469604913-12442-17-git-send-email-armbru@redhat.com>
9
+ Patchwork-id: 71484
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 15/15] json-streamer: fix double-free on exiting during a parse
11
+ Bugzilla: 1276036
12
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
13
+ RH-Acked-by: John Snow <jsnow@redhat.com>
14
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
15
+
16
+ From: Paolo Bonzini <pbonzini@redhat.com>
17
+
18
+ Now that json-streamer tries not to leak tokens on incomplete parse,
19
+ the tokens can be freed twice if QEMU destroys the json-streamer
20
+ object during the parser->emit call. To fix this, create the new
21
+ empty GQueue earlier, so that it is already in place when the old
22
+ one is passed to parser->emit.
23
+
24
+ Reported-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
25
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
26
+ Message-Id: <1467636059-12557-1-git-send-email-pbonzini@redhat.com>
27
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
28
+ (cherry picked from commit a942d8fa01f65279cdc135f4294db611bbc088ef)
29
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
30
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
31
+ ---
32
+ qobject/json-streamer.c | 8 ++++++--
33
+ 1 file changed, 6 insertions(+), 2 deletions(-)
34
+
35
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
36
+ index 3c7d6be..7d041e1 100644
37
+ --- a/qobject/json-streamer.c
38
+ +++ b/qobject/json-streamer.c
39
+ @@ -38,6 +38,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
40
+ {
41
+ JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
42
+ JSONToken *token;
43
+ + GQueue *tokens;
44
+
45
+ switch (type) {
46
+ case JSON_LCURLY:
47
+ @@ -95,9 +96,12 @@ out_emit:
48
+ /* send current list of tokens to parser and reset tokenizer */
49
+ parser->brace_count = 0;
50
+ parser->bracket_count = 0;
51
+ - /* parser->emit takes ownership of parser->tokens. */
52
+ - parser->emit(parser, parser->tokens);
53
+ + /* parser->emit takes ownership of parser->tokens. Remove our own
54
+ + * reference to parser->tokens before handing it out to parser->emit.
55
+ + */
56
+ + tokens = parser->tokens;
57
+ parser->tokens = g_queue_new();
58
+ + parser->emit(parser, tokens);
59
+ parser->token_size = 0;
60
+ }
61
+
62
+ --
63
+ 1.8.3.1
64
+
SOURCES/kvm-nbd-Always-call-close_fn-in-nbd_client_new.patch ADDED
@@ -0,0 +1,112 @@
1
+ From 2efca7904a7a71d44bdf715208899e3bb29711df Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Thu, 10 Mar 2016 04:00:51 +0100
4
+ Subject: [PATCH 2/5] nbd: Always call "close_fn" in nbd_client_new
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1457582453-13835-2-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69757
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/3] nbd: Always call "close_fn" in nbd_client_new
10
+ Bugzilla: 1285453
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
13
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
14
+
15
+ Rename the parameter "close" to "close_fn" to disambiguous with
16
+ close(2).
17
+
18
+ This unifies error handling paths of NBDClient allocation:
19
+ nbd_client_new will shutdown the socket and call the "close_fn" callback
20
+ if negotiation failed, so the caller don't need a different path than
21
+ the normal close.
22
+
23
+ The returned pointer is never used, make it void in preparation for the
24
+ next patch.
25
+
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+ Message-Id: <1452760863-25350-2-git-send-email-famz@redhat.com>
28
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
29
+ (cherry picked from commit ee7d7aabdaea4484e069cb99c9fc54e8cb24b56f)
30
+ Signed-off-by: Fam Zheng <famz@redhat.com>
31
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
32
+
33
+ Conflicts:
34
+ include/block/nbd.h
35
+ nbd.c
36
+ qemu-nbd.c
37
+ * nbd_update_server_fd_handler not in downstream;
38
+ * Context around the changed line is different.
39
+ ---
40
+ include/block/nbd.h | 3 +--
41
+ nbd.c | 11 +++++------
42
+ qemu-nbd.c | 4 ++--
43
+ 3 files changed, 8 insertions(+), 10 deletions(-)
44
+
45
+ diff --git a/include/block/nbd.h b/include/block/nbd.h
46
+ index c90f5e4..92e360e 100644
47
+ --- a/include/block/nbd.h
48
+ +++ b/include/block/nbd.h
49
+ @@ -92,8 +92,7 @@ NBDExport *nbd_export_find(const char *name);
50
+ void nbd_export_set_name(NBDExport *exp, const char *name);
51
+ void nbd_export_close_all(void);
52
+
53
+ -NBDClient *nbd_client_new(NBDExport *exp, int csock,
54
+ - void (*close)(NBDClient *));
55
+ +void nbd_client_new(NBDExport *exp, int csock, void (*close_fn)(NBDClient *));
56
+ void nbd_client_close(NBDClient *client);
57
+ void nbd_client_get(NBDClient *client);
58
+ void nbd_client_put(NBDClient *client);
59
+ diff --git a/nbd.c b/nbd.c
60
+ index f258cdd..ba97270 100644
61
+ --- a/nbd.c
62
+ +++ b/nbd.c
63
+ @@ -1232,8 +1232,7 @@ static void nbd_restart_write(void *opaque)
64
+ qemu_coroutine_enter(client->send_coroutine, NULL);
65
+ }
66
+
67
+ -NBDClient *nbd_client_new(NBDExport *exp, int csock,
68
+ - void (*close)(NBDClient *))
69
+ +void nbd_client_new(NBDExport *exp, int csock, void (*close_fn)(NBDClient *))
70
+ {
71
+ NBDClient *client;
72
+ client = g_malloc0(sizeof(NBDClient));
73
+ @@ -1241,10 +1240,11 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
74
+ client->exp = exp;
75
+ client->sock = csock;
76
+ if (nbd_send_negotiate(client) < 0) {
77
+ - g_free(client);
78
+ - return NULL;
79
+ + shutdown(client->sock, 2);
80
+ + close_fn(client);
81
+ + return;
82
+ }
83
+ - client->close = close;
84
+ + client->close = close_fn;
85
+ qemu_co_mutex_init(&client->send_lock);
86
+ qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
87
+
88
+ @@ -1252,5 +1252,4 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
89
+ QTAILQ_INSERT_TAIL(&exp->clients, client, next);
90
+ nbd_export_get(exp);
91
+ }
92
+ - return client;
93
+ }
94
+ diff --git a/qemu-nbd.c b/qemu-nbd.c
95
+ index ff792ef..047dd49 100644
96
+ --- a/qemu-nbd.c
97
+ +++ b/qemu-nbd.c
98
+ @@ -297,9 +297,9 @@ static void nbd_accept(void *opaque)
99
+ close(fd);
100
+ return;
101
+ }
102
+ -
103
+ - if (fd >= 0 && nbd_client_new(exp, fd, nbd_client_closed)) {
104
+ + if (fd >= 0) {
105
+ nb_fds++;
106
+ + nbd_client_new(exp, fd, nbd_client_closed);
107
+ }
108
+ }
109
+
110
+ --
111
+ 1.8.3.1
112
+
SOURCES/kvm-nbd-client_close-on-error-in-nbd_co_client_start.patch ADDED
@@ -0,0 +1,50 @@
1
+ From c62e0877b191e5fba9b678bbd518a57c8fdf7099 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Thu, 10 Mar 2016 04:00:53 +0100
4
+ Subject: [PATCH 4/5] nbd: client_close on error in nbd_co_client_start
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1457582453-13835-4-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69759
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 3/3] nbd: client_close on error in nbd_co_client_start
10
+ Bugzilla: 1285453
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
13
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
14
+
15
+ From: Max Reitz <mreitz@redhat.com>
16
+
17
+ Use client_close() if an error in nbd_co_client_start() occurs instead
18
+ of manually inlining parts of it. This fixes an assertion error on the
19
+ server side if nbd_negotiate() fails.
20
+
21
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
22
+ Acked-by: Paolo Bonzini <pbonzini@redhat.com>
23
+ Reviewed-by: Eric Blake <eblake@redhat.com>
24
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
+ (cherry picked from commit d3780c2dce2c452759ee9d94f9d824cf14cc3ab8)
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+
28
+ Downstream: client_close -> nbd_client_close.
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ nbd.c | 3 +--
32
+ 1 file changed, 1 insertion(+), 2 deletions(-)
33
+
34
+ diff --git a/nbd.c b/nbd.c
35
+ index 97aeecb..c20e57e 100644
36
+ --- a/nbd.c
37
+ +++ b/nbd.c
38
+ @@ -1282,8 +1282,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
39
+ nbd_export_get(exp);
40
+ }
41
+ if (nbd_negotiate(data)) {
42
+ - shutdown(client->sock, 2);
43
+ - client->close(client);
44
+ + nbd_client_close(client);
45
+ goto out;
46
+ }
47
+ qemu_co_mutex_init(&client->send_lock);
48
+ --
49
+ 1.8.3.1
50
+
SOURCES/kvm-nbd-server-Coroutine-based-negotiation.patch ADDED
@@ -0,0 +1,262 @@
1
+ From 2a68d801c63137c3d1fe9fa96f0193eb2d1576f5 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Thu, 10 Mar 2016 04:00:52 +0100
4
+ Subject: [PATCH 3/5] nbd-server: Coroutine based negotiation
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1457582453-13835-3-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69758
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/3] nbd-server: Coroutine based negotiation
10
+ Bugzilla: 1285453
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
13
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
14
+
15
+ Create a coroutine in nbd_client_new, so that nbd_send_negotiate doesn't
16
+ need qemu_set_block().
17
+
18
+ Handlers need to be set temporarily for csock fd in case the coroutine
19
+ yields during I/O.
20
+
21
+ With this, if the other end disappears in the middle of the negotiation,
22
+ we don't block the whole event loop.
23
+
24
+ To make the code clearer, unify all function names that belong to
25
+ negotiate, so they are less likely to be misused. This is important
26
+ because we rely on negotiation staying in main loop, as commented in
27
+ nbd_negotiate_read/write().
28
+
29
+ Signed-off-by: Fam Zheng <famz@redhat.com>
30
+ Message-Id: <1452760863-25350-4-git-send-email-famz@redhat.com>
31
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
32
+ (cherry picked from commit 1a6245a5b0b4e8d822c739b403fc67c8a7bc8d12)
33
+ Signed-off-by: Fam Zheng <famz@redhat.com>
34
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
35
+
36
+ Conflicts:
37
+ nbd.c
38
+ Downstream doesn't have new style protocol, and the code is not split.
39
+ The patch is redone.
40
+ ---
41
+ nbd.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++---------------
42
+ 1 file changed, 82 insertions(+), 24 deletions(-)
43
+
44
+ diff --git a/nbd.c b/nbd.c
45
+ index ba97270..97aeecb 100644
46
+ --- a/nbd.c
47
+ +++ b/nbd.c
48
+ @@ -167,6 +167,41 @@ ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
49
+ return offset;
50
+ }
51
+
52
+ +static void nbd_negotiate_continue(void *opaque)
53
+ +{
54
+ + qemu_coroutine_enter(opaque, NULL);
55
+ +}
56
+ +
57
+ +static ssize_t read_sync(int fd, void *buffer, size_t size);
58
+ +static ssize_t write_sync(int fd, void *buffer, size_t size);
59
+ +
60
+ +static ssize_t nbd_negotiate_read(int fd, void *buffer, size_t size)
61
+ +{
62
+ + ssize_t ret;
63
+ +
64
+ + assert(qemu_in_coroutine());
65
+ + /* Negotiation are always in main loop. */
66
+ + qemu_set_fd_handler(fd, nbd_negotiate_continue, NULL,
67
+ + qemu_coroutine_self());
68
+ + ret = read_sync(fd, buffer, size);
69
+ + qemu_set_fd_handler(fd, NULL, NULL, NULL);
70
+ + return ret;
71
+ +
72
+ +}
73
+ +
74
+ +static ssize_t nbd_negotiate_write(int fd, void *buffer, size_t size)
75
+ +{
76
+ + ssize_t ret;
77
+ +
78
+ + assert(qemu_in_coroutine());
79
+ + /* Negotiation are always in main loop. */
80
+ + qemu_set_fd_handler(fd, NULL, nbd_negotiate_continue,
81
+ + qemu_coroutine_self());
82
+ + ret = write_sync(fd, buffer, size);
83
+ + qemu_set_fd_handler(fd, NULL, NULL, NULL);
84
+ + return ret;
85
+ +}
86
+ +
87
+ static ssize_t read_sync(int fd, void *buffer, size_t size)
88
+ {
89
+ /* Sockets are kept in blocking mode in the negotiation phase. After
90
+ @@ -280,7 +315,7 @@ int unix_socket_outgoing(const char *path)
91
+
92
+ */
93
+
94
+ -static int nbd_receive_options(NBDClient *client)
95
+ +static coroutine_fn int nbd_negotiate_receive_options(NBDClient *client)
96
+ {
97
+ int csock = client->sock;
98
+ char name[256];
99
+ @@ -297,7 +332,7 @@ static int nbd_receive_options(NBDClient *client)
100
+ */
101
+
102
+ rc = -EINVAL;
103
+ - if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
104
+ + if (nbd_negotiate_read(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
105
+ LOG("read failed");
106
+ goto fail;
107
+ }
108
+ @@ -307,7 +342,7 @@ static int nbd_receive_options(NBDClient *client)
109
+ goto fail;
110
+ }
111
+
112
+ - if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
113
+ + if (nbd_negotiate_read(csock, &magic, sizeof(magic)) != sizeof(magic)) {
114
+ LOG("read failed");
115
+ goto fail;
116
+ }
117
+ @@ -317,7 +352,7 @@ static int nbd_receive_options(NBDClient *client)
118
+ goto fail;
119
+ }
120
+
121
+ - if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
122
+ + if (nbd_negotiate_read(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
123
+ LOG("read failed");
124
+ goto fail;
125
+ }
126
+ @@ -327,7 +362,7 @@ static int nbd_receive_options(NBDClient *client)
127
+ goto fail;
128
+ }
129
+
130
+ - if (read_sync(csock, &length, sizeof(length)) != sizeof(length)) {
131
+ + if (nbd_negotiate_read(csock, &length, sizeof(length)) != sizeof(length)) {
132
+ LOG("read failed");
133
+ goto fail;
134
+ }
135
+ @@ -337,7 +372,7 @@ static int nbd_receive_options(NBDClient *client)
136
+ LOG("Bad length received");
137
+ goto fail;
138
+ }
139
+ - if (read_sync(csock, name, length) != length) {
140
+ + if (nbd_negotiate_read(csock, name, length) != length) {
141
+ LOG("read failed");
142
+ goto fail;
143
+ }
144
+ @@ -358,8 +393,14 @@ fail:
145
+ return rc;
146
+ }
147
+
148
+ -static int nbd_send_negotiate(NBDClient *client)
149
+ +typedef struct {
150
+ + NBDClient *client;
151
+ + Coroutine *co;
152
+ +} NBDClientNewData;
153
+ +
154
+ +static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
155
+ {
156
+ + NBDClient *client = data->client;
157
+ int csock = client->sock;
158
+ char buf[8 + 8 + 8 + 128];
159
+ int rc;
160
+ @@ -385,7 +426,6 @@ static int nbd_send_negotiate(NBDClient *client)
161
+ [28 .. 151] reserved (0)
162
+ */
163
+
164
+ - qemu_set_block(csock);
165
+ rc = -EINVAL;
166
+
167
+ TRACE("Beginning negotiation.");
168
+ @@ -401,16 +441,16 @@ static int nbd_send_negotiate(NBDClient *client)
169
+ }
170
+
171
+ if (client->exp) {
172
+ - if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
173
+ + if (nbd_negotiate_write(csock, buf, sizeof(buf)) != sizeof(buf)) {
174
+ LOG("write failed");
175
+ goto fail;
176
+ }
177
+ } else {
178
+ - if (write_sync(csock, buf, 18) != 18) {
179
+ + if (nbd_negotiate_write(csock, buf, 18) != 18) {
180
+ LOG("write failed");
181
+ goto fail;
182
+ }
183
+ - rc = nbd_receive_options(client);
184
+ + rc = nbd_negotiate_receive_options(client);
185
+ if (rc < 0) {
186
+ LOG("option negotiation failed");
187
+ goto fail;
188
+ @@ -419,7 +459,8 @@ static int nbd_send_negotiate(NBDClient *client)
189
+ assert ((client->exp->nbdflags & ~65535) == 0);
190
+ cpu_to_be64w((uint64_t*)(buf + 18), client->exp->size);
191
+ cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
192
+ - if (write_sync(csock, buf + 18, sizeof(buf) - 18) != sizeof(buf) - 18) {
193
+ + if (nbd_negotiate_write(csock, buf + 18,
194
+ + sizeof(buf) - 18) != sizeof(buf) - 18) {
195
+ LOG("write failed");
196
+ goto fail;
197
+ }
198
+ @@ -428,7 +469,6 @@ static int nbd_send_negotiate(NBDClient *client)
199
+ TRACE("Negotiation succeeded.");
200
+ rc = 0;
201
+ fail:
202
+ - qemu_set_nonblock(csock);
203
+ return rc;
204
+ }
205
+
206
+ @@ -1232,24 +1272,42 @@ static void nbd_restart_write(void *opaque)
207
+ qemu_coroutine_enter(client->send_coroutine, NULL);
208
+ }
209
+
210
+ +static coroutine_fn void nbd_co_client_start(void *opaque)
211
+ +{
212
+ + NBDClientNewData *data = opaque;
213
+ + NBDClient *client = data->client;
214
+ + NBDExport *exp = client->exp;
215
+ +
216
+ + if (exp) {
217
+ + nbd_export_get(exp);
218
+ + }
219
+ + if (nbd_negotiate(data)) {
220
+ + shutdown(client->sock, 2);
221
+ + client->close(client);
222
+ + goto out;
223
+ + }
224
+ + qemu_co_mutex_init(&client->send_lock);
225
+ + qemu_set_fd_handler2(client->sock, nbd_can_read, nbd_read, NULL, client);
226
+ +
227
+ + if (exp) {
228
+ + QTAILQ_INSERT_TAIL(&exp->clients, client, next);
229
+ + }
230
+ +out:
231
+ + g_free(data);
232
+ +}
233
+ +
234
+ void nbd_client_new(NBDExport *exp, int csock, void (*close_fn)(NBDClient *))
235
+ {
236
+ NBDClient *client;
237
+ + NBDClientNewData *data = g_new(NBDClientNewData, 1);
238
+ +
239
+ client = g_malloc0(sizeof(NBDClient));
240
+ client->refcount = 1;
241
+ client->exp = exp;
242
+ client->sock = csock;
243
+ - if (nbd_send_negotiate(client) < 0) {
244
+ - shutdown(client->sock, 2);
245
+ - close_fn(client);
246
+ - return;
247
+ - }
248
+ client->close = close_fn;
249
+ - qemu_co_mutex_init(&client->send_lock);
250
+ - qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
251
+
252
+ - if (exp) {
253
+ - QTAILQ_INSERT_TAIL(&exp->clients, client, next);
254
+ - nbd_export_get(exp);
255
+ - }
256
+ + data->client = client;
257
+ + data->co = qemu_coroutine_create(nbd_co_client_start);
258
+ + qemu_coroutine_enter(data->co, data);
259
+ }
260
+ --
261
+ 1.8.3.1
262
+
SOURCES/kvm-nbd-server-Set-O_NONBLOCK-on-client-fd.patch ADDED
@@ -0,0 +1,44 @@
1
+ From e36a5a8613df42339773ebf48e07d063ad7484e8 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 5 Sep 2016 01:18:15 +0200
4
+ Subject: [PATCH] nbd-server: Set O_NONBLOCK on client fd
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1473038295-7193-1-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 72141
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH] nbd-server: Set O_NONBLOCK on client fd
10
+ Bugzilla: 1285453
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ Upstream: upstream uses IO channels that is not present in downstream.
16
+ Backporting that deserves a separate and deliberate justification BZ,
17
+ for 7.4.
18
+
19
+ Even with 2a68d80 (nbd-server: Coroutine based negotiation), QEMU still
20
+ hangs when client hangs, because recvmsg the socket fd is blocking. Set
21
+ the O_NONBLOCK to fix this.
22
+
23
+ Analyzed-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ Signed-off-by: Fam Zheng <famz@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ nbd.c | 1 +
28
+ 1 file changed, 1 insertion(+)
29
+
30
+ diff --git a/nbd.c b/nbd.c
31
+ index c20e57e..8a32e18 100644
32
+ --- a/nbd.c
33
+ +++ b/nbd.c
34
+ @@ -1281,6 +1281,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
35
+ if (exp) {
36
+ nbd_export_get(exp);
37
+ }
38
+ + qemu_set_nonblock(client->sock);
39
+ if (nbd_negotiate(data)) {
40
+ nbd_client_close(client);
41
+ goto out;
42
+ --
43
+ 1.8.3.1
44
+
SOURCES/kvm-net-Make-qmp_query_rx_filter-with-name-argument-more.patch ADDED
@@ -0,0 +1,47 @@
1
+ From 9c2a6798c053cec989e02935e810a0d239fb493c Mon Sep 17 00:00:00 2001
2
+ From: Vlad Yasevich <vyasevic@redhat.com>
3
+ Date: Wed, 16 Dec 2015 02:59:35 +0100
4
+ Subject: [PATCH 1/2] net: Make qmp_query_rx_filter() with name argument more
5
+ obvious
6
+
7
+ RH-Author: Vlad Yasevich <vyasevic@redhat.com>
8
+ Message-id: <1450234776-7779-2-git-send-email-vyasevic@redhat.com>
9
+ Patchwork-id: 68620
10
+ O-Subject: [RHEL7.3 qemu-kvm PATCH 1/2] net: Make qmp_query_rx_filter() with name argument more obvious
11
+ Bugzilla: 1269738
12
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
15
+
16
+ From: Markus Armbruster <armbru@redhat.com>
17
+
18
+ With a client name, the QMP command is specified to return a list of
19
+ one element. This isn't locally obvious in the code. Make it so.
20
+
21
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
22
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
23
+ (cherry picked from commit 638fb14169ad96cf9bc0dd5f61460daaecee5bb1)
24
+ Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ net/net.c | 4 ++++
28
+ 1 file changed, 4 insertions(+)
29
+
30
+ diff --git a/net/net.c b/net/net.c
31
+ index a8c49fc..0be50a0 100644
32
+ --- a/net/net.c
33
+ +++ b/net/net.c
34
+ @@ -1000,6 +1000,10 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name,
35
+ " rx-filter querying", name);
36
+ break;
37
+ }
38
+ +
39
+ + if (has_name) {
40
+ + break;
41
+ + }
42
+ }
43
+
44
+ if (filter_list == NULL && !error_is_set(errp) && has_name) {
45
+ --
46
+ 1.8.3.1
47
+
SOURCES/kvm-pc-set-the-OEM-fields-in-the-RSDT-and-the-FADT-from-.patch ADDED
@@ -0,0 +1,133 @@
1
+ From 607904cf94b1dee91c74522aedebda308ffba93d Mon Sep 17 00:00:00 2001
2
+ From: Laszlo Ersek <lersek@redhat.com>
3
+ Date: Wed, 11 May 2016 12:33:48 +0200
4
+ Subject: [PATCH 09/10] pc: set the OEM fields in the RSDT and the FADT from
5
+ the SLIC
6
+
7
+ RH-Author: Laszlo Ersek <lersek@redhat.com>
8
+ Message-id: <1462970028-10959-8-git-send-email-lersek@redhat.com>
9
+ Patchwork-id: 70384
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 7/7] pc: set the OEM fields in the RSDT and the FADT from the SLIC
11
+ Bugzilla: 1330969
12
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
13
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
14
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
15
+
16
+ The Microsoft spec about the SLIC and MSDM ACPI tables at
17
+ <http://go.microsoft.com/fwlink/p/?LinkId=234834> requires the OEM ID and
18
+ OEM Table ID fields to be consistent between the SLIC and the RSDT/XSDT.
19
+ That further affects the FADT, because a similar match between the FADT
20
+ and the RSDT/XSDT is required by the ACPI spec in general.
21
+
22
+ This patch wires up the previous three patches.
23
+
24
+ Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
25
+ Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
26
+ Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
27
+ Cc: Richard W.M. Jones <rjones@redhat.com>
28
+ Cc: Aleksei Kovura <alex3kov@zoho.com>
29
+ Cc: Michael Tokarev <mjt@tls.msk.ru>
30
+ Cc: Steven Newbury <steve@snewbury.org.uk>
31
+ RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
32
+ LP: https://bugs.launchpad.net/qemu/+bug/1533848
33
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
34
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
35
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
36
+ Reviewed-by: Steven Newbury <steve@snewbury.org.uk>
37
+ (cherry picked from commit ae12374951f07157f7a52c8d848b90f8eec722fb)
38
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
39
+
40
+ Conflicts:
41
+ hw/i386/acpi-build.c
42
+
43
+ RHEL-7 backport note: conflict due to downstream lacking 7c2c1fa5f428
44
+ ("pc: acpi: use local var for accessing ACPI tables blob in
45
+ acpi_build()").
46
+
47
+ Signed-off-by: Laszlo Ersek <lersek@redhat.com>
48
+ ---
49
+ hw/i386/acpi-build.c | 13 +++++++++----
50
+ qemu-options.hx | 4 ++++
51
+ 2 files changed, 13 insertions(+), 4 deletions(-)
52
+ ---
53
+ hw/i386/acpi-build.c | 13 +++++++++----
54
+ qemu-options.hx | 4 ++++
55
+ 2 files changed, 13 insertions(+), 4 deletions(-)
56
+
57
+ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
58
+ index d9433e6..85291f5 100644
59
+ --- a/hw/i386/acpi-build.c
60
+ +++ b/hw/i386/acpi-build.c
61
+ @@ -511,7 +511,8 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
62
+ /* FADT */
63
+ static void
64
+ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
65
+ - unsigned facs, unsigned dsdt)
66
+ + unsigned facs, unsigned dsdt,
67
+ + const char *oem_id, const char *oem_table_id)
68
+ {
69
+ AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
70
+
71
+ @@ -532,7 +533,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
72
+ fadt_setup(fadt, pm);
73
+
74
+ build_header(linker, table_data,
75
+ - (void *)fadt, "FACP", sizeof(*fadt), 1, NULL, NULL);
76
+ + (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
77
+ }
78
+
79
+ static void
80
+ @@ -1065,6 +1066,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
81
+ AcpiMcfgInfo mcfg;
82
+ PcPciInfo pci;
83
+ uint8_t *u;
84
+ + AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
85
+
86
+ acpi_get_cpu_info(&cpu);
87
+ acpi_get_pm_info(&pm);
88
+ @@ -1072,6 +1074,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
89
+ acpi_get_hotplug_info(&misc);
90
+ acpi_get_misc_info(&misc);
91
+ acpi_get_pci_info(&pci);
92
+ + acpi_get_slic_oem(&slic_oem);
93
+
94
+ table_offsets = g_array_new(false, true /* clear */,
95
+ sizeof(uint32_t));
96
+ @@ -1095,7 +1098,8 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
97
+
98
+ /* ACPI tables pointed to by RSDT */
99
+ acpi_add_table(table_offsets, tables->table_data);
100
+ - build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
101
+ + build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt,
102
+ + slic_oem.id, slic_oem.table_id);
103
+
104
+ acpi_add_table(table_offsets, tables->table_data);
105
+ build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
106
+ @@ -1127,7 +1131,8 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
107
+
108
+ /* RSDT is pointed to by RSDP */
109
+ rsdt = tables->table_data->len;
110
+ - build_rsdt(tables->table_data, tables->linker, table_offsets, NULL, NULL);
111
+ + build_rsdt(tables->table_data, tables->linker, table_offsets,
112
+ + slic_oem.id, slic_oem.table_id);
113
+
114
+ /* RSDP is in FSEG memory, so allocate it separately */
115
+ build_rsdp(tables->rsdp, tables->linker, rsdt);
116
+ diff --git a/qemu-options.hx b/qemu-options.hx
117
+ index 62c3e06..24ffab6 100644
118
+ --- a/qemu-options.hx
119
+ +++ b/qemu-options.hx
120
+ @@ -1295,6 +1295,10 @@ ACPI headers (possible overridden by other options).
121
+ For data=, only data
122
+ portion of the table is used, all header information is specified in the
123
+ command line.
124
+ +If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
125
+ +fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
126
+ +to ensure the field matches required by the Microsoft SLIC spec and the ACPI
127
+ +spec.
128
+ ETEXI
129
+
130
+ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
131
+ --
132
+ 1.8.3.1
133
+
SOURCES/kvm-qemu-io-Check-for-trailing-chars.patch ADDED
@@ -0,0 +1,59 @@
1
+ From 362faad8e8f4c2c2c875df12f6bbae7964c0146d Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:38 +0100
4
+ Subject: [PATCH 19/27] qemu-io: Check for trailing chars
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-20-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68449
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 19/21] qemu-io: Check for trailing chars
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ Make sure there's not trailing garbage, e.g.
16
+ "64k-whatever-i-want-here"
17
+
18
+ Reported-by: Max Reitz <mreitz@redhat.com>
19
+ Signed-off-by: John Snow <jsnow@redhat.com>
20
+ Reviewed-by: Eric Blake <eblake@redhat.com>
21
+ Reviewed-by: Kevin Wolf <kwolf@redhat.com>
22
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
+ (cherry picked from commit ef5a788527b2038d742b057a415ab4d0e735e98f)
24
+ Signed-off-by: John Snow <jsnow@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+
27
+ Conflicts:
28
+ qemu-io-cmds.c:
29
+ - Downstream still uses strtosz_suffix, not
30
+ qemu_strtosz_suffix.
31
+
32
+ Signed-off-by: John Snow <jsnow@redhat.com>
33
+ ---
34
+ qemu-io-cmds.c | 9 ++++++++-
35
+ 1 file changed, 8 insertions(+), 1 deletion(-)
36
+
37
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
38
+ index 95345fe..6ea027d 100644
39
+ --- a/qemu-io-cmds.c
40
+ +++ b/qemu-io-cmds.c
41
+ @@ -124,7 +124,14 @@ static char **breakline(char *input, int *count)
42
+ static int64_t cvtnum(const char *s)
43
+ {
44
+ char *end;
45
+ - return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
46
+ + int64_t ret;
47
+ +
48
+ + ret = strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
49
+ + if (*end != '\0') {
50
+ + /* Detritus at the end of the string */
51
+ + return -EINVAL;
52
+ + }
53
+ + return ret;
54
+ }
55
+
56
+ #define EXABYTES(x) ((long long)(x) << 60)
57
+ --
58
+ 1.8.3.1
59
+
SOURCES/kvm-qemu-io-Correct-error-messages.patch ADDED
@@ -0,0 +1,218 @@
1
+ From 8adbd2914ccd44e0b1766690b514bda213b88740 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:39 +0100
4
+ Subject: [PATCH 20/27] qemu-io: Correct error messages
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-21-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68446
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 20/21] qemu-io: Correct error messages
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ Reported-by: Max Reitz <mreitz@redhat.com>
16
+ Signed-off-by: John Snow <jsnow@redhat.com>
17
+ Reviewed-by: Eric Blake <eblake@redhat.com>
18
+ Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
+ (cherry picked from commit a9ecfa004f2dd83df612daac4a87dfc3a0feba28)
21
+ Signed-off-by: John Snow <jsnow@redhat.com>
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+
24
+ Conflicts:
25
+ qemu-io-cmds.c:
26
+ - Fixes to sigraise are not backported.
27
+
28
+ Signed-off-by: John Snow <jsnow@redhat.com>
29
+ ---
30
+ qemu-io-cmds.c | 51 +++++++++++++++++++++++++++++++++------------------
31
+ 1 file changed, 33 insertions(+), 18 deletions(-)
32
+
33
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
34
+ index 6ea027d..b41d6ee 100644
35
+ --- a/qemu-io-cmds.c
36
+ +++ b/qemu-io-cmds.c
37
+ @@ -134,6 +134,21 @@ static int64_t cvtnum(const char *s)
38
+ return ret;
39
+ }
40
+
41
+ +static void print_cvtnum_err(int64_t rc, const char *arg)
42
+ +{
43
+ + switch (rc) {
44
+ + case -EINVAL:
45
+ + printf("Parsing error: non-numeric argument,"
46
+ + " or extraneous/unrecognized suffix -- %s\n", arg);
47
+ + break;
48
+ + case -ERANGE:
49
+ + printf("Parsing error: argument too large -- %s\n", arg);
50
+ + break;
51
+ + default:
52
+ + printf("Parsing error: %s\n", arg);
53
+ + }
54
+ +}
55
+ +
56
+ #define EXABYTES(x) ((long long)(x) << 60)
57
+ #define PETABYTES(x) ((long long)(x) << 50)
58
+ #define TERABYTES(x) ((long long)(x) << 40)
59
+ @@ -355,13 +370,13 @@ create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
60
+
61
+ len = cvtnum(arg);
62
+ if (len < 0) {
63
+ - printf("non-numeric length argument -- %s\n", arg);
64
+ + print_cvtnum_err(len, arg);
65
+ goto fail;
66
+ }
67
+
68
+ /* should be SIZE_T_MAX, but that doesn't exist */
69
+ if (len > INT_MAX) {
70
+ - printf("too large length argument -- %s\n", arg);
71
+ + printf("Argument '%s' exceeds maximum size %d\n", arg, INT_MAX);
72
+ goto fail;
73
+ }
74
+
75
+ @@ -688,7 +703,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
76
+ lflag = 1;
77
+ pattern_count = cvtnum(optarg);
78
+ if (pattern_count < 0) {
79
+ - printf("non-numeric length argument -- %s\n", optarg);
80
+ + print_cvtnum_err(pattern_count, optarg);
81
+ return 0;
82
+ }
83
+ break;
84
+ @@ -709,7 +724,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
85
+ sflag = 1;
86
+ pattern_offset = cvtnum(optarg);
87
+ if (pattern_offset < 0) {
88
+ - printf("non-numeric length argument -- %s\n", optarg);
89
+ + print_cvtnum_err(pattern_offset, optarg);
90
+ return 0;
91
+ }
92
+ break;
93
+ @@ -732,14 +747,14 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
94
+
95
+ offset = cvtnum(argv[optind]);
96
+ if (offset < 0) {
97
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
98
+ + print_cvtnum_err(offset, argv[optind]);
99
+ return 0;
100
+ }
101
+
102
+ optind++;
103
+ count = cvtnum(argv[optind]);
104
+ if (count < 0) {
105
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
106
+ + print_cvtnum_err(count, argv[optind]);
107
+ return 0;
108
+ } else if (count > SIZE_MAX) {
109
+ printf("length cannot exceed %" PRIu64 ", given %s\n",
110
+ @@ -894,7 +909,7 @@ static int readv_f(BlockDriverState *bs, int argc, char **argv)
111
+
112
+ offset = cvtnum(argv[optind]);
113
+ if (offset < 0) {
114
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
115
+ + print_cvtnum_err(offset, argv[optind]);
116
+ return 0;
117
+ }
118
+ optind++;
119
+ @@ -1043,14 +1058,14 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
120
+
121
+ offset = cvtnum(argv[optind]);
122
+ if (offset < 0) {
123
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
124
+ + print_cvtnum_err(offset, argv[optind]);
125
+ return 0;
126
+ }
127
+
128
+ optind++;
129
+ count = cvtnum(argv[optind]);
130
+ if (count < 0) {
131
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
132
+ + print_cvtnum_err(count, argv[optind]);
133
+ return 0;
134
+ } else if (count > SIZE_MAX) {
135
+ printf("length cannot exceed %" PRIu64 ", given %s\n",
136
+ @@ -1179,7 +1194,7 @@ static int writev_f(BlockDriverState *bs, int argc, char **argv)
137
+
138
+ offset = cvtnum(argv[optind]);
139
+ if (offset < 0) {
140
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
141
+ + print_cvtnum_err(offset, argv[optind]);
142
+ return 0;
143
+ }
144
+ optind++;
145
+ @@ -1306,7 +1321,7 @@ static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
146
+ /* Read the offset of the request */
147
+ offset = cvtnum(argv[optind]);
148
+ if (offset < 0) {
149
+ - printf("non-numeric offset argument -- %s\n", argv[optind]);
150
+ + print_cvtnum_err(offset, argv[optind]);
151
+ goto out;
152
+ }
153
+ optind++;
154
+ @@ -1526,7 +1541,7 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
155
+
156
+ ctx->offset = cvtnum(argv[optind]);
157
+ if (ctx->offset < 0) {
158
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
159
+ + print_cvtnum_err(ctx->offset, argv[optind]);
160
+ g_free(ctx);
161
+ return 0;
162
+ }
163
+ @@ -1618,7 +1633,7 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
164
+
165
+ ctx->offset = cvtnum(argv[optind]);
166
+ if (ctx->offset < 0) {
167
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
168
+ + print_cvtnum_err(ctx->offset, argv[optind]);
169
+ g_free(ctx);
170
+ return 0;
171
+ }
172
+ @@ -1676,7 +1691,7 @@ static int truncate_f(BlockDriverState *bs, int argc, char **argv)
173
+
174
+ offset = cvtnum(argv[1]);
175
+ if (offset < 0) {
176
+ - printf("non-numeric truncate argument -- %s\n", argv[1]);
177
+ + print_cvtnum_err(offset, argv[1]);
178
+ return 0;
179
+ }
180
+
181
+ @@ -1822,14 +1837,14 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
182
+
183
+ offset = cvtnum(argv[optind]);
184
+ if (offset < 0) {
185
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
186
+ + print_cvtnum_err(offset, argv[optind]);
187
+ return 0;
188
+ }
189
+
190
+ optind++;
191
+ count = cvtnum(argv[optind]);
192
+ if (count < 0) {
193
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
194
+ + print_cvtnum_err(count, argv[optind]);
195
+ return 0;
196
+ } else if (count >> BDRV_SECTOR_BITS > INT_MAX) {
197
+ printf("length cannot exceed %"PRIu64", given %s\n",
198
+ @@ -1867,7 +1882,7 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
199
+
200
+ offset = cvtnum(argv[1]);
201
+ if (offset < 0) {
202
+ - printf("non-numeric offset argument -- %s\n", argv[1]);
203
+ + print_cvtnum_err(offset, argv[1]);
204
+ return 0;
205
+ } else if (offset & 0x1ff) {
206
+ printf("offset %" PRId64 " is not sector aligned\n",
207
+ @@ -1878,7 +1893,7 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
208
+ if (argc == 3) {
209
+ nb_sectors = cvtnum(argv[2]);
210
+ if (nb_sectors < 0) {
211
+ - printf("non-numeric length argument -- %s\n", argv[2]);
212
+ + print_cvtnum_err(nb_sectors, argv[2]);
213
+ return 0;
214
+ } else if (nb_sectors > INT_MAX) {
215
+ printf("length argument cannot exceed %d, given %s\n",
216
+ --
217
+ 1.8.3.1
218
+
SOURCES/kvm-qemu-io-Don-t-use-global-bs-in-command-implementatio.patch ADDED
@@ -0,0 +1,737 @@
1
+ From 2653e21a25d8fb99479337c785e81b07f755acda Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:24 +0100
4
+ Subject: [PATCH 05/27] qemu-io: Don't use global bs in command implementations
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-6-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68433
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 05/21] qemu-io: Don't use global bs in command implementations
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Pass in the BlockDriverState to the command handlers instead of using
18
+ the global variable. This is an important step to make the commands
19
+ usable outside of qemu-io.
20
+
21
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
+ Reviewed-by: Eric Blake <eblake@redhat.com>
23
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ (cherry picked from commit 734c3b85cb72d264ad2b38a87f30304e05de2cb1)
25
+ Signed-off-by: John Snow <jsnow@redhat.com>
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+
28
+ Conflicts:
29
+ qemu-io.c
30
+ Number of arguments to bdrv_co_write_zeroes
31
+ bdrv_unref used downstream instead of bdrv_delete
32
+ downstream, local_err used for bdrv_open
33
+ downstream, error_abort used for bdrv_new
34
+ map_is_allocated was never backported from a00e81e98f71
35
+ sleep_f was backported, adjust its signature
36
+
37
+ Signed-off-by: John Snow <jsnow@redhat.com>
38
+ ---
39
+ cmd.c | 6 ++-
40
+ cmd.h | 8 ++-
41
+ qemu-io.c | 164 ++++++++++++++++++++++++++++++++++----------------------------
42
+ 3 files changed, 99 insertions(+), 79 deletions(-)
43
+
44
+ diff --git a/cmd.c b/cmd.c
45
+ index 214c6f7..d501aab 100644
46
+ --- a/cmd.c
47
+ +++ b/cmd.c
48
+ @@ -57,7 +57,7 @@ check_command(
49
+ const cmdinfo_t *ci)
50
+ {
51
+ if (check_func)
52
+ - return check_func(ci);
53
+ + return check_func(qemuio_bs, ci);
54
+ return 1;
55
+ }
56
+
57
+ @@ -103,7 +103,7 @@ command(
58
+ return 0;
59
+ }
60
+ optind = 0;
61
+ - return ct->cfunc(argc, argv);
62
+ + return ct->cfunc(qemuio_bs, argc, argv);
63
+ }
64
+
65
+ const cmdinfo_t *
66
+ @@ -452,6 +452,7 @@ static cmdinfo_t quit_cmd;
67
+ /* ARGSUSED */
68
+ static int
69
+ quit_f(
70
+ + BlockDriverState *bs,
71
+ int argc,
72
+ char **argv)
73
+ {
74
+ @@ -490,6 +491,7 @@ help_all(void)
75
+
76
+ static int
77
+ help_f(
78
+ + BlockDriverState *bs,
79
+ int argc,
80
+ char **argv)
81
+ {
82
+ diff --git a/cmd.h b/cmd.h
83
+ index 4dcfe88..ccf6336 100644
84
+ --- a/cmd.h
85
+ +++ b/cmd.h
86
+ @@ -17,9 +17,13 @@
87
+ #ifndef __COMMAND_H__
88
+ #define __COMMAND_H__
89
+
90
+ +#include "qemu-common.h"
91
+ +
92
+ #define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */
93
+
94
+ -typedef int (*cfunc_t)(int argc, char **argv);
95
+ +extern BlockDriverState *qemuio_bs;
96
+ +
97
+ +typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
98
+ typedef void (*helpfunc_t)(void);
99
+
100
+ typedef struct cmdinfo {
101
+ @@ -41,7 +45,7 @@ extern int ncmds;
102
+ void help_init(void);
103
+ void quit_init(void);
104
+
105
+ -typedef int (*checkfunc_t)(const cmdinfo_t *ci);
106
+ +typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
107
+
108
+ void add_command(const cmdinfo_t *ci);
109
+ void add_user_command(char *optarg);
110
+ diff --git a/qemu-io.c b/qemu-io.c
111
+ index e4fa2fc..c3cc4f3 100644
112
+ --- a/qemu-io.c
113
+ +++ b/qemu-io.c
114
+ @@ -29,8 +29,8 @@
115
+ #define CMD_NOFILE_OK 0x01
116
+
117
+ char *progname;
118
+ -static BlockDriverState *bs;
119
+
120
+ +BlockDriverState *qemuio_bs;
121
+ static int misalign;
122
+
123
+ static int64_t cvtnum(const char *s)
124
+ @@ -67,7 +67,7 @@ static int parse_pattern(const char *arg)
125
+ */
126
+
127
+ #define MISALIGN_OFFSET 16
128
+ -static void *qemu_io_alloc(size_t len, int pattern)
129
+ +static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
130
+ {
131
+ void *buf;
132
+
133
+ @@ -140,7 +140,8 @@ static void print_report(const char *op, struct timeval *t, int64_t offset,
134
+ * vector matching it.
135
+ */
136
+ static void *
137
+ -create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
138
+ +create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
139
+ + int pattern)
140
+ {
141
+ size_t *sizes = g_new0(size_t, nr_iov);
142
+ size_t count = 0;
143
+ @@ -176,7 +177,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
144
+
145
+ qemu_iovec_init(qiov, nr_iov);
146
+
147
+ - buf = p = qemu_io_alloc(count, pattern);
148
+ + buf = p = qemu_io_alloc(bs, count, pattern);
149
+
150
+ for (i = 0; i < nr_iov; i++) {
151
+ qemu_iovec_add(qiov, p, sizes[i]);
152
+ @@ -188,7 +189,8 @@ fail:
153
+ return buf;
154
+ }
155
+
156
+ -static int do_read(char *buf, int64_t offset, int count, int *total)
157
+ +static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
158
+ + int *total)
159
+ {
160
+ int ret;
161
+
162
+ @@ -200,7 +202,8 @@ static int do_read(char *buf, int64_t offset, int count, int *total)
163
+ return 1;
164
+ }
165
+
166
+ -static int do_write(char *buf, int64_t offset, int count, int *total)
167
+ +static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
168
+ + int *total)
169
+ {
170
+ int ret;
171
+
172
+ @@ -212,7 +215,8 @@ static int do_write(char *buf, int64_t offset, int count, int *total)
173
+ return 1;
174
+ }
175
+
176
+ -static int do_pread(char *buf, int64_t offset, int count, int *total)
177
+ +static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
178
+ + int *total)
179
+ {
180
+ *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
181
+ if (*total < 0) {
182
+ @@ -221,7 +225,8 @@ static int do_pread(char *buf, int64_t offset, int count, int *total)
183
+ return 1;
184
+ }
185
+
186
+ -static int do_pwrite(char *buf, int64_t offset, int count, int *total)
187
+ +static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
188
+ + int *total)
189
+ {
190
+ *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
191
+ if (*total < 0) {
192
+ @@ -231,6 +236,7 @@ static int do_pwrite(char *buf, int64_t offset, int count, int *total)
193
+ }
194
+
195
+ typedef struct {
196
+ + BlockDriverState *bs;
197
+ int64_t offset;
198
+ int count;
199
+ int *total;
200
+ @@ -242,7 +248,7 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
201
+ {
202
+ CoWriteZeroes *data = opaque;
203
+
204
+ - data->ret = bdrv_co_write_zeroes(bs, data->offset / BDRV_SECTOR_SIZE,
205
+ + data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
206
+ data->count / BDRV_SECTOR_SIZE, 0);
207
+ data->done = true;
208
+ if (data->ret < 0) {
209
+ @@ -253,10 +259,12 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
210
+ *data->total = data->count;
211
+ }
212
+
213
+ -static int do_co_write_zeroes(int64_t offset, int count, int *total)
214
+ +static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
215
+ + int *total)
216
+ {
217
+ Coroutine *co;
218
+ CoWriteZeroes data = {
219
+ + .bs = bs,
220
+ .offset = offset,
221
+ .count = count,
222
+ .total = total,
223
+ @@ -275,7 +283,8 @@ static int do_co_write_zeroes(int64_t offset, int count, int *total)
224
+ }
225
+ }
226
+
227
+ -static int do_write_compressed(char *buf, int64_t offset, int count, int *total)
228
+ +static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
229
+ + int count, int *total)
230
+ {
231
+ int ret;
232
+
233
+ @@ -287,7 +296,8 @@ static int do_write_compressed(char *buf, int64_t offset, int count, int *total)
234
+ return 1;
235
+ }
236
+
237
+ -static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
238
+ +static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
239
+ + int count, int *total)
240
+ {
241
+ *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
242
+ if (*total < 0) {
243
+ @@ -296,7 +306,8 @@ static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
244
+ return 1;
245
+ }
246
+
247
+ -static int do_save_vmstate(char *buf, int64_t offset, int count, int *total)
248
+ +static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
249
+ + int count, int *total)
250
+ {
251
+ *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
252
+ if (*total < 0) {
253
+ @@ -311,7 +322,8 @@ static void aio_rw_done(void *opaque, int ret)
254
+ *(int *)opaque = ret;
255
+ }
256
+
257
+ -static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
258
+ +static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
259
+ + int64_t offset, int *total)
260
+ {
261
+ int async_ret = NOT_DONE;
262
+
263
+ @@ -325,7 +337,8 @@ static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
264
+ return async_ret < 0 ? async_ret : 1;
265
+ }
266
+
267
+ -static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
268
+ +static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
269
+ + int64_t offset, int *total)
270
+ {
271
+ int async_ret = NOT_DONE;
272
+
273
+ @@ -354,7 +367,8 @@ static void multiwrite_cb(void *opaque, int ret)
274
+ }
275
+ }
276
+
277
+ -static int do_aio_multiwrite(BlockRequest* reqs, int num_reqs, int *total)
278
+ +static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
279
+ + int num_reqs, int *total)
280
+ {
281
+ int i, ret;
282
+ struct multiwrite_async_ret async_ret = {
283
+ @@ -403,7 +417,7 @@ static void read_help(void)
284
+ "\n");
285
+ }
286
+
287
+ -static int read_f(int argc, char **argv);
288
+ +static int read_f(BlockDriverState *bs, int argc, char **argv);
289
+
290
+ static const cmdinfo_t read_cmd = {
291
+ .name = "read",
292
+ @@ -416,7 +430,7 @@ static const cmdinfo_t read_cmd = {
293
+ .help = read_help,
294
+ };
295
+
296
+ -static int read_f(int argc, char **argv)
297
+ +static int read_f(BlockDriverState *bs, int argc, char **argv)
298
+ {
299
+ struct timeval t1, t2;
300
+ int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
301
+ @@ -522,15 +536,15 @@ static int read_f(int argc, char **argv)
302
+ }
303
+ }
304
+
305
+ - buf = qemu_io_alloc(count, 0xab);
306
+ + buf = qemu_io_alloc(bs, count, 0xab);
307
+
308
+ gettimeofday(&t1, NULL);
309
+ if (pflag) {
310
+ - cnt = do_pread(buf, offset, count, &total);
311
+ + cnt = do_pread(bs, buf, offset, count, &total);
312
+ } else if (bflag) {
313
+ - cnt = do_load_vmstate(buf, offset, count, &total);
314
+ + cnt = do_load_vmstate(bs, buf, offset, count, &total);
315
+ } else {
316
+ - cnt = do_read(buf, offset, count, &total);
317
+ + cnt = do_read(bs, buf, offset, count, &total);
318
+ }
319
+ gettimeofday(&t2, NULL);
320
+
321
+ @@ -587,7 +601,7 @@ static void readv_help(void)
322
+ "\n");
323
+ }
324
+
325
+ -static int readv_f(int argc, char **argv);
326
+ +static int readv_f(BlockDriverState *bs, int argc, char **argv);
327
+
328
+ static const cmdinfo_t readv_cmd = {
329
+ .name = "readv",
330
+ @@ -599,7 +613,7 @@ static const cmdinfo_t readv_cmd = {
331
+ .help = readv_help,
332
+ };
333
+
334
+ -static int readv_f(int argc, char **argv)
335
+ +static int readv_f(BlockDriverState *bs, int argc, char **argv)
336
+ {
337
+ struct timeval t1, t2;
338
+ int Cflag = 0, qflag = 0, vflag = 0;
339
+ @@ -655,13 +669,13 @@ static int readv_f(int argc, char **argv)
340
+ }
341
+
342
+ nr_iov = argc - optind;
343
+ - buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
344
+ + buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
345
+ if (buf == NULL) {
346
+ return 0;
347
+ }
348
+
349
+ gettimeofday(&t1, NULL);
350
+ - cnt = do_aio_readv(&qiov, offset, &total);
351
+ + cnt = do_aio_readv(bs, &qiov, offset, &total);
352
+ gettimeofday(&t2, NULL);
353
+
354
+ if (cnt < 0) {
355
+ @@ -718,7 +732,7 @@ static void write_help(void)
356
+ "\n");
357
+ }
358
+
359
+ -static int write_f(int argc, char **argv);
360
+ +static int write_f(BlockDriverState *bs, int argc, char **argv);
361
+
362
+ static const cmdinfo_t write_cmd = {
363
+ .name = "write",
364
+ @@ -731,7 +745,7 @@ static const cmdinfo_t write_cmd = {
365
+ .help = write_help,
366
+ };
367
+
368
+ -static int write_f(int argc, char **argv)
369
+ +static int write_f(BlockDriverState *bs, int argc, char **argv)
370
+ {
371
+ struct timeval t1, t2;
372
+ int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
373
+ @@ -818,20 +832,20 @@ static int write_f(int argc, char **argv)
374
+ }
375
+
376
+ if (!zflag) {
377
+ - buf = qemu_io_alloc(count, pattern);
378
+ + buf = qemu_io_alloc(bs, count, pattern);
379
+ }
380
+
381
+ gettimeofday(&t1, NULL);
382
+ if (pflag) {
383
+ - cnt = do_pwrite(buf, offset, count, &total);
384
+ + cnt = do_pwrite(bs, buf, offset, count, &total);
385
+ } else if (bflag) {
386
+ - cnt = do_save_vmstate(buf, offset, count, &total);
387
+ + cnt = do_save_vmstate(bs, buf, offset, count, &total);
388
+ } else if (zflag) {
389
+ - cnt = do_co_write_zeroes(offset, count, &total);
390
+ + cnt = do_co_write_zeroes(bs, offset, count, &total);
391
+ } else if (cflag) {
392
+ - cnt = do_write_compressed(buf, offset, count, &total);
393
+ + cnt = do_write_compressed(bs, buf, offset, count, &total);
394
+ } else {
395
+ - cnt = do_write(buf, offset, count, &total);
396
+ + cnt = do_write(bs, buf, offset, count, &total);
397
+ }
398
+ gettimeofday(&t2, NULL);
399
+
400
+ @@ -874,7 +888,7 @@ writev_help(void)
401
+ "\n");
402
+ }
403
+
404
+ -static int writev_f(int argc, char **argv);
405
+ +static int writev_f(BlockDriverState *bs, int argc, char **argv);
406
+
407
+ static const cmdinfo_t writev_cmd = {
408
+ .name = "writev",
409
+ @@ -886,7 +900,7 @@ static const cmdinfo_t writev_cmd = {
410
+ .help = writev_help,
411
+ };
412
+
413
+ -static int writev_f(int argc, char **argv)
414
+ +static int writev_f(BlockDriverState *bs, int argc, char **argv)
415
+ {
416
+ struct timeval t1, t2;
417
+ int Cflag = 0, qflag = 0;
418
+ @@ -936,13 +950,13 @@ static int writev_f(int argc, char **argv)
419
+ }
420
+
421
+ nr_iov = argc - optind;
422
+ - buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
423
+ + buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
424
+ if (buf == NULL) {
425
+ return 0;
426
+ }
427
+
428
+ gettimeofday(&t1, NULL);
429
+ - cnt = do_aio_writev(&qiov, offset, &total);
430
+ + cnt = do_aio_writev(bs, &qiov, offset, &total);
431
+ gettimeofday(&t2, NULL);
432
+
433
+ if (cnt < 0) {
434
+ @@ -983,7 +997,7 @@ static void multiwrite_help(void)
435
+ "\n");
436
+ }
437
+
438
+ -static int multiwrite_f(int argc, char **argv);
439
+ +static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
440
+
441
+ static const cmdinfo_t multiwrite_cmd = {
442
+ .name = "multiwrite",
443
+ @@ -995,7 +1009,7 @@ static const cmdinfo_t multiwrite_cmd = {
444
+ .help = multiwrite_help,
445
+ };
446
+
447
+ -static int multiwrite_f(int argc, char **argv)
448
+ +static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
449
+ {
450
+ struct timeval t1, t2;
451
+ int Cflag = 0, qflag = 0;
452
+ @@ -1076,7 +1090,7 @@ static int multiwrite_f(int argc, char **argv)
453
+ nr_iov = j - optind;
454
+
455
+ /* Build request */
456
+ - buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern);
457
+ + buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
458
+ if (buf[i] == NULL) {
459
+ goto out;
460
+ }
461
+ @@ -1094,7 +1108,7 @@ static int multiwrite_f(int argc, char **argv)
462
+ nr_reqs = i;
463
+
464
+ gettimeofday(&t1, NULL);
465
+ - cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
466
+ + cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
467
+ gettimeofday(&t2, NULL);
468
+
469
+ if (cnt < 0) {
470
+ @@ -1222,7 +1236,7 @@ static void aio_read_help(void)
471
+ "\n");
472
+ }
473
+
474
+ -static int aio_read_f(int argc, char **argv);
475
+ +static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
476
+
477
+ static const cmdinfo_t aio_read_cmd = {
478
+ .name = "aio_read",
479
+ @@ -1234,7 +1248,7 @@ static const cmdinfo_t aio_read_cmd = {
480
+ .help = aio_read_help,
481
+ };
482
+
483
+ -static int aio_read_f(int argc, char **argv)
484
+ +static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
485
+ {
486
+ int nr_iov, c;
487
+ struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
488
+ @@ -1285,7 +1299,7 @@ static int aio_read_f(int argc, char **argv)
489
+ }
490
+
491
+ nr_iov = argc - optind;
492
+ - ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
493
+ + ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
494
+ if (ctx->buf == NULL) {
495
+ g_free(ctx);
496
+ return 0;
497
+ @@ -1317,7 +1331,7 @@ static void aio_write_help(void)
498
+ "\n");
499
+ }
500
+
501
+ -static int aio_write_f(int argc, char **argv);
502
+ +static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
503
+
504
+ static const cmdinfo_t aio_write_cmd = {
505
+ .name = "aio_write",
506
+ @@ -1329,7 +1343,7 @@ static const cmdinfo_t aio_write_cmd = {
507
+ .help = aio_write_help,
508
+ };
509
+
510
+ -static int aio_write_f(int argc, char **argv)
511
+ +static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
512
+ {
513
+ int nr_iov, c;
514
+ int pattern = 0xcd;
515
+ @@ -1377,7 +1391,7 @@ static int aio_write_f(int argc, char **argv)
516
+ }
517
+
518
+ nr_iov = argc - optind;
519
+ - ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
520
+ + ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
521
+ if (ctx->buf == NULL) {
522
+ g_free(ctx);
523
+ return 0;
524
+ @@ -1389,7 +1403,7 @@ static int aio_write_f(int argc, char **argv)
525
+ return 0;
526
+ }
527
+
528
+ -static int aio_flush_f(int argc, char **argv)
529
+ +static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
530
+ {
531
+ bdrv_drain_all();
532
+ return 0;
533
+ @@ -1401,7 +1415,7 @@ static const cmdinfo_t aio_flush_cmd = {
534
+ .oneline = "completes all outstanding aio requests"
535
+ };
536
+
537
+ -static int flush_f(int argc, char **argv)
538
+ +static int flush_f(BlockDriverState *bs, int argc, char **argv)
539
+ {
540
+ bdrv_flush(bs);
541
+ return 0;
542
+ @@ -1414,7 +1428,7 @@ static const cmdinfo_t flush_cmd = {
543
+ .oneline = "flush all in-core file state to disk",
544
+ };
545
+
546
+ -static int truncate_f(int argc, char **argv)
547
+ +static int truncate_f(BlockDriverState *bs, int argc, char **argv)
548
+ {
549
+ int64_t offset;
550
+ int ret;
551
+ @@ -1444,7 +1458,7 @@ static const cmdinfo_t truncate_cmd = {
552
+ .oneline = "truncates the current file at the given offset",
553
+ };
554
+
555
+ -static int length_f(int argc, char **argv)
556
+ +static int length_f(BlockDriverState *bs, int argc, char **argv)
557
+ {
558
+ int64_t size;
559
+ char s1[64];
560
+ @@ -1469,7 +1483,7 @@ static const cmdinfo_t length_cmd = {
561
+ };
562
+
563
+
564
+ -static int info_f(int argc, char **argv)
565
+ +static int info_f(BlockDriverState *bs, int argc, char **argv)
566
+ {
567
+ BlockDriverInfo bdi;
568
+ ImageInfoSpecific *spec_info;
569
+ @@ -1528,7 +1542,7 @@ static void discard_help(void)
570
+ "\n");
571
+ }
572
+
573
+ -static int discard_f(int argc, char **argv);
574
+ +static int discard_f(BlockDriverState *bs, int argc, char **argv);
575
+
576
+ static const cmdinfo_t discard_cmd = {
577
+ .name = "discard",
578
+ @@ -1541,7 +1555,7 @@ static const cmdinfo_t discard_cmd = {
579
+ .help = discard_help,
580
+ };
581
+
582
+ -static int discard_f(int argc, char **argv)
583
+ +static int discard_f(BlockDriverState *bs, int argc, char **argv)
584
+ {
585
+ struct timeval t1, t2;
586
+ int Cflag = 0, qflag = 0;
587
+ @@ -1599,7 +1613,7 @@ out:
588
+ return 0;
589
+ }
590
+
591
+ -static int alloc_f(int argc, char **argv)
592
+ +static int alloc_f(BlockDriverState *bs, int argc, char **argv)
593
+ {
594
+ int64_t offset, sector_num;
595
+ int nb_sectors, remaining;
596
+ @@ -1664,7 +1678,7 @@ static const cmdinfo_t alloc_cmd = {
597
+ .oneline = "checks if a sector is present in the file",
598
+ };
599
+
600
+ -static int map_f(int argc, char **argv)
601
+ +static int map_f(BlockDriverState *bs, int argc, char **argv)
602
+ {
603
+ int64_t offset;
604
+ int64_t nb_sectors;
605
+ @@ -1700,7 +1714,7 @@ static const cmdinfo_t map_cmd = {
606
+ .oneline = "prints the allocated areas of a file",
607
+ };
608
+
609
+ -static int break_f(int argc, char **argv)
610
+ +static int break_f(BlockDriverState *bs, int argc, char **argv)
611
+ {
612
+ int ret;
613
+
614
+ @@ -1722,7 +1736,7 @@ static const cmdinfo_t break_cmd = {
615
+ "request as tag",
616
+ };
617
+
618
+ -static int resume_f(int argc, char **argv)
619
+ +static int resume_f(BlockDriverState *bs, int argc, char **argv)
620
+ {
621
+ int ret;
622
+
623
+ @@ -1743,7 +1757,7 @@ static const cmdinfo_t resume_cmd = {
624
+ .oneline = "resumes the request tagged as tag",
625
+ };
626
+
627
+ -static int wait_break_f(int argc, char **argv)
628
+ +static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
629
+ {
630
+ while (!bdrv_debug_is_suspended(bs, argv[1])) {
631
+ qemu_aio_wait();
632
+ @@ -1761,7 +1775,7 @@ static const cmdinfo_t wait_break_cmd = {
633
+ .oneline = "waits for the suspension of a request",
634
+ };
635
+
636
+ -static int abort_f(int argc, char **argv)
637
+ +static int abort_f(BlockDriverState *bs, int argc, char **argv)
638
+ {
639
+ abort();
640
+ }
641
+ @@ -1773,10 +1787,10 @@ static const cmdinfo_t abort_cmd = {
642
+ .oneline = "simulate a program crash using abort(3)",
643
+ };
644
+
645
+ -static int close_f(int argc, char **argv)
646
+ +static int close_f(BlockDriverState *bs, int argc, char **argv)
647
+ {
648
+ bdrv_unref(bs);
649
+ - bs = NULL;
650
+ + qemuio_bs = NULL;
651
+ return 0;
652
+ }
653
+
654
+ @@ -1793,7 +1807,7 @@ static void sleep_cb(void *opaque)
655
+ *expired = true;
656
+ }
657
+
658
+ -static int sleep_f(int argc, char **argv)
659
+ +static int sleep_f(BlockDriverState *bs, int argc, char **argv)
660
+ {
661
+ char *endptr;
662
+ long ms;
663
+ @@ -1831,27 +1845,27 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
664
+ {
665
+ Error *local_err = NULL;
666
+
667
+ - if (bs) {
668
+ + if (qemuio_bs) {
669
+ fprintf(stderr, "file open already, try 'help close'\n");
670
+ return 1;
671
+ }
672
+
673
+ if (growable) {
674
+ - if (bdrv_file_open(&bs, name, opts, flags, &local_err)) {
675
+ + if (bdrv_file_open(&qemuio_bs, name, opts, flags, &local_err)) {
676
+ fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
677
+ error_get_pretty(local_err));
678
+ error_free(local_err);
679
+ return 1;
680
+ }
681
+ } else {
682
+ - bs = bdrv_new("hda", &error_abort);
683
+ + qemuio_bs = bdrv_new("hda", &error_abort);
684
+
685
+ - if (bdrv_open(bs, name, opts, flags, NULL, &local_err) < 0) {
686
+ + if (bdrv_open(qemuio_bs, name, opts, flags, NULL, &local_err) < 0) {
687
+ fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
688
+ error_get_pretty(local_err));
689
+ error_free(local_err);
690
+ - bdrv_unref(bs);
691
+ - bs = NULL;
692
+ + bdrv_unref(qemuio_bs);
693
+ + qemuio_bs = NULL;
694
+ return 1;
695
+ }
696
+ }
697
+ @@ -1877,7 +1891,7 @@ static void open_help(void)
698
+ "\n");
699
+ }
700
+
701
+ -static int open_f(int argc, char **argv);
702
+ +static int open_f(BlockDriverState *bs, int argc, char **argv);
703
+
704
+ static const cmdinfo_t open_cmd = {
705
+ .name = "open",
706
+ @@ -1900,7 +1914,7 @@ static QemuOptsList empty_opts = {
707
+ },
708
+ };
709
+
710
+ -static int open_f(int argc, char **argv)
711
+ +static int open_f(BlockDriverState *bs, int argc, char **argv)
712
+ {
713
+ int flags = 0;
714
+ int readonly = 0;
715
+ @@ -1948,7 +1962,7 @@ static int open_f(int argc, char **argv)
716
+ return openfile(argv[optind], flags, growable, opts);
717
+ }
718
+
719
+ -static int init_check_command(const cmdinfo_t *ct)
720
+ +static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
721
+ {
722
+ if (ct->flags & CMD_FLAG_GLOBAL) {
723
+ return 1;
724
+ @@ -2117,8 +2131,8 @@ int main(int argc, char **argv)
725
+ */
726
+ bdrv_drain_all();
727
+
728
+ - if (bs) {
729
+ - bdrv_unref(bs);
730
+ + if (qemuio_bs) {
731
+ + bdrv_unref(qemuio_bs);
732
+ }
733
+ return 0;
734
+ }
735
+ --
736
+ 1.8.3.1
737
+
SOURCES/kvm-qemu-io-Factor-out-qemuio_command.patch ADDED
@@ -0,0 +1,163 @@
1
+ From c73b87743086200c3f9ad485dcd4e71bdee27881 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:26 +0100
4
+ Subject: [PATCH 07/27] qemu-io: Factor out qemuio_command
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-8-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68438
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 07/21] qemu-io: Factor out qemuio_command
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ It's duplicated code. Move it to qemu-io-cmds.c because it's not
18
+ dependent on any static data of the qemu-io tool.
19
+
20
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
+ Reviewed-by: Eric Blake <eblake@redhat.com>
22
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
23
+ (cherry picked from commit dd5832967ac3fe96bd5bf9f199639176998ead69)
24
+ Signed-off-by: John Snow <jsnow@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ cmd.c | 43 +++++--------------------------------------
28
+ cmd.h | 3 ++-
29
+ qemu-io-cmds.c | 24 ++++++++++++++++++++++++
30
+ 3 files changed, 31 insertions(+), 39 deletions(-)
31
+
32
+ diff --git a/cmd.c b/cmd.c
33
+ index d501aab..7ae978f 100644
34
+ --- a/cmd.c
35
+ +++ b/cmd.c
36
+ @@ -138,28 +138,11 @@ static char *get_prompt(void);
37
+
38
+ void command_loop(void)
39
+ {
40
+ - int c, i, done = 0, fetchable = 0, prompted = 0;
41
+ + int i, done = 0, fetchable = 0, prompted = 0;
42
+ char *input;
43
+ - char **v;
44
+ - const cmdinfo_t *ct;
45
+
46
+ for (i = 0; !done && i < ncmdline; i++) {
47
+ - input = strdup(cmdline[i]);
48
+ - if (!input) {
49
+ - fprintf(stderr, _("cannot strdup command '%s': %s\n"),
50
+ - cmdline[i], strerror(errno));
51
+ - exit(1);
52
+ - }
53
+ - v = breakline(input, &c);
54
+ - if (c) {
55
+ - ct = find_command(v[0]);
56
+ - if (ct) {
57
+ - done = command(ct, c, v);
58
+ - } else {
59
+ - fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
60
+ - }
61
+ - }
62
+ - doneline(input, v);
63
+ + done = qemuio_command(cmdline[i]);
64
+ }
65
+ if (cmdline) {
66
+ g_free(cmdline);
67
+ @@ -179,20 +162,13 @@ void command_loop(void)
68
+ if (!fetchable) {
69
+ continue;
70
+ }
71
+ +
72
+ input = fetchline();
73
+ if (input == NULL) {
74
+ break;
75
+ }
76
+ - v = breakline(input, &c);
77
+ - if (c) {
78
+ - ct = find_command(v[0]);
79
+ - if (ct) {
80
+ - done = command(ct, c, v);
81
+ - } else {
82
+ - fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
83
+ - }
84
+ - }
85
+ - doneline(input, v);
86
+ + done = qemuio_command(input);
87
+ + free(input);
88
+
89
+ prompted = 0;
90
+ fetchable = 0;
91
+ @@ -328,15 +304,6 @@ char **breakline(char *input, int *count)
92
+ return rval;
93
+ }
94
+
95
+ -void
96
+ -doneline(
97
+ - char *input,
98
+ - char **vec)
99
+ -{
100
+ - free(input);
101
+ - free(vec);
102
+ -}
103
+ -
104
+ #define EXABYTES(x) ((long long)(x) << 60)
105
+ #define PETABYTES(x) ((long long)(x) << 50)
106
+ #define TERABYTES(x) ((long long)(x) << 40)
107
+ diff --git a/cmd.h b/cmd.h
108
+ index ccf6336..d676408 100644
109
+ --- a/cmd.h
110
+ +++ b/cmd.h
111
+ @@ -59,7 +59,6 @@ int command(const cmdinfo_t *ci, int argc, char **argv);
112
+
113
+ /* from input.h */
114
+ char **breakline(char *input, int *count);
115
+ -void doneline(char *input, char **vec);
116
+ char *fetchline(void);
117
+
118
+ void cvtstr(double value, char *str, size_t sz);
119
+ @@ -77,4 +76,6 @@ void timestr(struct timeval *tv, char *str, size_t sz, int flags);
120
+
121
+ extern char *progname;
122
+
123
+ +bool qemuio_command(const char *cmd);
124
+ +
125
+ #endif /* __COMMAND_H__ */
126
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
127
+ index efa6070..09e4099 100644
128
+ --- a/qemu-io-cmds.c
129
+ +++ b/qemu-io-cmds.c
130
+ @@ -1824,6 +1824,30 @@ static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
131
+ return 1;
132
+ }
133
+
134
+ +bool qemuio_command(const char *cmd)
135
+ +{
136
+ + char *input;
137
+ + const cmdinfo_t *ct;
138
+ + char **v;
139
+ + int c;
140
+ + bool done = false;
141
+ +
142
+ + input = g_strdup(cmd);
143
+ + v = breakline(input, &c);
144
+ + if (c) {
145
+ + ct = find_command(v[0]);
146
+ + if (ct) {
147
+ + done = command(ct, c, v);
148
+ + } else {
149
+ + fprintf(stderr, "command \"%s\" not found\n", v[0]);
150
+ + }
151
+ + }
152
+ + g_free(input);
153
+ + g_free(v);
154
+ +
155
+ + return done;
156
+ +}
157
+ +
158
+ static void __attribute((constructor)) init_qemuio_commands(void)
159
+ {
160
+ /* initialize commands */
161
+ --
162
+ 1.8.3.1
163
+
SOURCES/kvm-qemu-io-Handle-cvtnum-errors-in-alloc.patch ADDED
@@ -0,0 +1,56 @@
1
+ From 862f45e0ad5a70d10bffa435d5331c444874e4d2 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:23 +0100
4
+ Subject: [PATCH 04/27] qemu-io: Handle cvtnum() errors in 'alloc'
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-5-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68431
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 04/21] qemu-io: Handle cvtnum() errors in 'alloc'
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
+ Reviewed-by: Eric Blake <eblake@redhat.com>
19
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
+ (cherry picked from commit cf49a6a00c19cabf4006d4f82bef26345043e7b5)
21
+ Signed-off-by: John Snow <jsnow@redhat.com>
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+ ---
24
+ qemu-io.c | 9 ++++++++-
25
+ 1 file changed, 8 insertions(+), 1 deletion(-)
26
+
27
+ diff --git a/qemu-io.c b/qemu-io.c
28
+ index 3b5890e..e4fa2fc 100644
29
+ --- a/qemu-io.c
30
+ +++ b/qemu-io.c
31
+ @@ -1608,7 +1608,10 @@ static int alloc_f(int argc, char **argv)
32
+ int ret;
33
+
34
+ offset = cvtnum(argv[1]);
35
+ - if (offset & 0x1ff) {
36
+ + if (offset < 0) {
37
+ + printf("non-numeric offset argument -- %s\n", argv[1]);
38
+ + return 0;
39
+ + } else if (offset & 0x1ff) {
40
+ printf("offset %" PRId64 " is not sector aligned\n",
41
+ offset);
42
+ return 0;
43
+ @@ -1616,6 +1619,10 @@ static int alloc_f(int argc, char **argv)
44
+
45
+ if (argc == 3) {
46
+ nb_sectors = cvtnum(argv[2]);
47
+ + if (nb_sectors < 0) {
48
+ + printf("non-numeric length argument -- %s\n", argv[2]);
49
+ + return 0;
50
+ + }
51
+ } else {
52
+ nb_sectors = 1;
53
+ }
54
+ --
55
+ 1.8.3.1
56
+
SOURCES/kvm-qemu-io-Interface-cleanup.patch ADDED
@@ -0,0 +1,240 @@
1
+ From 0dfb1b6f831f5b2a1fdf5e77330db3c95db2e464 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:33 +0100
4
+ Subject: [PATCH 14/27] qemu-io: Interface cleanup
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-15-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68444
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 14/21] qemu-io: Interface cleanup
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
+ (cherry picked from commit 3d21994f9c511cb63220fef5abea164b83fbb997)
20
+ Signed-off-by: John Snow <jsnow@redhat.com>
21
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
22
+
23
+ Conflicts:
24
+ qemu-io-cmds.c: include block/qapi.h context
25
+ qemu-io.c include block/qapi.h context
26
+
27
+ Signed-off-by: John Snow <jsnow@redhat.com>
28
+ ---
29
+ cmd.h | 48 ------------------------------------------------
30
+ include/qemu-io.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
31
+ qemu-io-cmds.c | 14 +++++++-------
32
+ qemu-io.c | 7 +++----
33
+ 4 files changed, 56 insertions(+), 59 deletions(-)
34
+ delete mode 100644 cmd.h
35
+ create mode 100644 include/qemu-io.h
36
+
37
+ diff --git a/cmd.h b/cmd.h
38
+ deleted file mode 100644
39
+ index 9907795..0000000
40
+ --- a/cmd.h
41
+ +++ /dev/null
42
+ @@ -1,48 +0,0 @@
43
+ -/*
44
+ - * Copyright (c) 2000-2005 Silicon Graphics, Inc.
45
+ - * All Rights Reserved.
46
+ - *
47
+ - * This program is free software; you can redistribute it and/or
48
+ - * modify it under the terms of the GNU General Public License as
49
+ - * published by the Free Software Foundation.
50
+ - *
51
+ - * This program is distributed in the hope that it would be useful,
52
+ - * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
+ - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54
+ - * GNU General Public License for more details.
55
+ - *
56
+ - * You should have received a copy of the GNU General Public License
57
+ - * along with this program; if not, see <http://www.gnu.org/licenses/>.
58
+ - */
59
+ -#ifndef __COMMAND_H__
60
+ -#define __COMMAND_H__
61
+ -
62
+ -#include "qemu-common.h"
63
+ -
64
+ -#define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */
65
+ -
66
+ -extern BlockDriverState *qemuio_bs;
67
+ -
68
+ -typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
69
+ -typedef void (*helpfunc_t)(void);
70
+ -
71
+ -typedef struct cmdinfo {
72
+ - const char *name;
73
+ - const char *altname;
74
+ - cfunc_t cfunc;
75
+ - int argmin;
76
+ - int argmax;
77
+ - int canpush;
78
+ - int flags;
79
+ - const char *args;
80
+ - const char *oneline;
81
+ - helpfunc_t help;
82
+ -} cmdinfo_t;
83
+ -
84
+ -void qemuio_add_command(const cmdinfo_t *ci);
85
+ -
86
+ -int qemuio_command_usage(const cmdinfo_t *ci);
87
+ -
88
+ -bool qemuio_command(const char *cmd);
89
+ -
90
+ -#endif /* __COMMAND_H__ */
91
+ diff --git a/include/qemu-io.h b/include/qemu-io.h
92
+ new file mode 100644
93
+ index 0000000..a418b46
94
+ --- /dev/null
95
+ +++ b/include/qemu-io.h
96
+ @@ -0,0 +1,46 @@
97
+ +/*
98
+ + * Copyright (c) 2000-2005 Silicon Graphics, Inc.
99
+ + * All Rights Reserved.
100
+ + *
101
+ + * This program is free software; you can redistribute it and/or
102
+ + * modify it under the terms of the GNU General Public License as
103
+ + * published by the Free Software Foundation.
104
+ + *
105
+ + * This program is distributed in the hope that it would be useful,
106
+ + * but WITHOUT ANY WARRANTY; without even the implied warranty of
107
+ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108
+ + * GNU General Public License for more details.
109
+ + *
110
+ + * You should have received a copy of the GNU General Public License
111
+ + * along with this program; if not, see <http://www.gnu.org/licenses/>.
112
+ + */
113
+ +
114
+ +#ifndef QEMU_IO_H
115
+ +#define QEMU_IO_H
116
+ +
117
+ +#include "qemu-common.h"
118
+ +
119
+ +#define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */
120
+ +
121
+ +typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
122
+ +typedef void (*helpfunc_t)(void);
123
+ +
124
+ +typedef struct cmdinfo {
125
+ + const char* name;
126
+ + const char* altname;
127
+ + cfunc_t cfunc;
128
+ + int argmin;
129
+ + int argmax;
130
+ + int canpush;
131
+ + int flags;
132
+ + const char *args;
133
+ + const char *oneline;
134
+ + helpfunc_t help;
135
+ +} cmdinfo_t;
136
+ +
137
+ +bool qemuio_command(BlockDriverState *bs, const char *cmd);
138
+ +
139
+ +void qemuio_add_command(const cmdinfo_t *ci);
140
+ +int qemuio_command_usage(const cmdinfo_t *ci);
141
+ +
142
+ +#endif /* QEMU_IO_H */
143
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
144
+ index 1db7fb9..1f21ce9 100644
145
+ --- a/qemu-io-cmds.c
146
+ +++ b/qemu-io-cmds.c
147
+ @@ -8,10 +8,9 @@
148
+ * See the COPYING file in the top-level directory.
149
+ */
150
+
151
+ -#include "qemu-common.h"
152
+ +#include "qemu-io.h"
153
+ #include "block/block_int.h"
154
+ #include "block/qapi.h"
155
+ -#include "cmd.h"
156
+
157
+ #define CMD_NOFILE_OK 0x01
158
+
159
+ @@ -51,11 +50,12 @@ static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
160
+ return 1;
161
+ }
162
+
163
+ -static int command(const cmdinfo_t *ct, int argc, char **argv)
164
+ +static int command(BlockDriverState *bs, const cmdinfo_t *ct, int argc,
165
+ + char **argv)
166
+ {
167
+ char *cmd = argv[0];
168
+
169
+ - if (!init_check_command(qemuio_bs, ct)) {
170
+ + if (!init_check_command(bs, ct)) {
171
+ return 0;
172
+ }
173
+
174
+ @@ -76,7 +76,7 @@ static int command(const cmdinfo_t *ct, int argc, char **argv)
175
+ return 0;
176
+ }
177
+ optind = 0;
178
+ - return ct->cfunc(qemuio_bs, argc, argv);
179
+ + return ct->cfunc(bs, argc, argv);
180
+ }
181
+
182
+ static const cmdinfo_t *find_command(const char *cmd)
183
+ @@ -2084,7 +2084,7 @@ static const cmdinfo_t help_cmd = {
184
+ .oneline = "help for one or all commands",
185
+ };
186
+
187
+ -bool qemuio_command(const char *cmd)
188
+ +bool qemuio_command(BlockDriverState *bs, const char *cmd)
189
+ {
190
+ char *input;
191
+ const cmdinfo_t *ct;
192
+ @@ -2097,7 +2097,7 @@ bool qemuio_command(const char *cmd)
193
+ if (c) {
194
+ ct = find_command(v[0]);
195
+ if (ct) {
196
+ - done = command(ct, c, v);
197
+ + done = command(bs, ct, c, v);
198
+ } else {
199
+ fprintf(stderr, "command \"%s\" not found\n", v[0]);
200
+ }
201
+ diff --git a/qemu-io.c b/qemu-io.c
202
+ index da9944e..e685808 100644
203
+ --- a/qemu-io.c
204
+ +++ b/qemu-io.c
205
+ @@ -14,13 +14,12 @@
206
+ #include <getopt.h>
207
+ #include <libgen.h>
208
+
209
+ -#include "qemu-common.h"
210
+ +#include "qemu-io.h"
211
+ #include "qemu/main-loop.h"
212
+ #include "qemu/option.h"
213
+ #include "qemu/config-file.h"
214
+ #include "block/block_int.h"
215
+ #include "block/qapi.h"
216
+ -#include "cmd.h"
217
+ #include "trace/control.h"
218
+ #include "qemu/timer.h"
219
+
220
+ @@ -306,7 +305,7 @@ static void command_loop(void)
221
+ char *input;
222
+
223
+ for (i = 0; !done && i < ncmdline; i++) {
224
+ - done = qemuio_command(cmdline[i]);
225
+ + done = qemuio_command(qemuio_bs, cmdline[i]);
226
+ }
227
+ if (cmdline) {
228
+ g_free(cmdline);
229
+ @@ -331,7 +330,7 @@ static void command_loop(void)
230
+ if (input == NULL) {
231
+ break;
232
+ }
233
+ - done = qemuio_command(input);
234
+ + done = qemuio_command(qemuio_bs, input);
235
+ g_free(input);
236
+
237
+ prompted = 0;
238
+ --
239
+ 1.8.3.1
240
+
SOURCES/kvm-qemu-io-Make-cvtnum-a-wrapper-around-strtosz_suffix.patch ADDED
@@ -0,0 +1,112 @@
1
+ From 94787daf53d6eb2936704f7d9089b26cc5803699 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:22 +0100
4
+ Subject: [PATCH 03/27] qemu-io: Make cvtnum() a wrapper around
5
+ strtosz_suffix()
6
+
7
+ RH-Author: John Snow <jsnow@redhat.com>
8
+ Message-id: <1448300320-7772-4-git-send-email-jsnow@redhat.com>
9
+ Patchwork-id: 68432
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 03/21] qemu-io: Make cvtnum() a wrapper around strtosz_suffix()
11
+ Bugzilla: 1272523
12
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
15
+
16
+ From: Kevin Wolf <kwolf@redhat.com>
17
+
18
+ No reason to implement the same thing multiple times. A nice side effect
19
+ is that fractional numbers like 0.5M can be used in qemu-io now.
20
+
21
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
+ Reviewed-by: Eric Blake <eblake@redhat.com>
23
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ (cherry picked from commit b6e356aa25c81d928e1c463292048d29cf25f04e)
25
+ Signed-off-by: John Snow <jsnow@redhat.com>
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+ ---
28
+ cmd.c | 37 -------------------------------------
29
+ cmd.h | 1 -
30
+ qemu-io.c | 6 ++++++
31
+ 3 files changed, 6 insertions(+), 38 deletions(-)
32
+
33
+ diff --git a/cmd.c b/cmd.c
34
+ index 4e7579b..214c6f7 100644
35
+ --- a/cmd.c
36
+ +++ b/cmd.c
37
+ @@ -344,43 +344,6 @@ doneline(
38
+ #define MEGABYTES(x) ((long long)(x) << 20)
39
+ #define KILOBYTES(x) ((long long)(x) << 10)
40
+
41
+ -long long
42
+ -cvtnum(
43
+ - char *s)
44
+ -{
45
+ - long long i;
46
+ - char *sp;
47
+ - int c;
48
+ -
49
+ - i = strtoll(s, &sp, 0);
50
+ - if (i == 0 && sp == s)
51
+ - return -1LL;
52
+ - if (*sp == '\0')
53
+ - return i;
54
+ -
55
+ - if (sp[1] != '\0')
56
+ - return -1LL;
57
+ -
58
+ - c = qemu_tolower(*sp);
59
+ - switch (c) {
60
+ - default:
61
+ - return i;
62
+ - case 'k':
63
+ - return KILOBYTES(i);
64
+ - case 'm':
65
+ - return MEGABYTES(i);
66
+ - case 'g':
67
+ - return GIGABYTES(i);
68
+ - case 't':
69
+ - return TERABYTES(i);
70
+ - case 'p':
71
+ - return PETABYTES(i);
72
+ - case 'e':
73
+ - return EXABYTES(i);
74
+ - }
75
+ - return -1LL;
76
+ -}
77
+ -
78
+ #define TO_EXABYTES(x) ((x) / EXABYTES(1))
79
+ #define TO_PETABYTES(x) ((x) / PETABYTES(1))
80
+ #define TO_TERABYTES(x) ((x) / TERABYTES(1))
81
+ diff --git a/cmd.h b/cmd.h
82
+ index 8e6f753..4dcfe88 100644
83
+ --- a/cmd.h
84
+ +++ b/cmd.h
85
+ @@ -58,7 +58,6 @@ char **breakline(char *input, int *count);
86
+ void doneline(char *input, char **vec);
87
+ char *fetchline(void);
88
+
89
+ -long long cvtnum(char *s);
90
+ void cvtstr(double value, char *str, size_t sz);
91
+
92
+ struct timeval tsub(struct timeval t1, struct timeval t2);
93
+ diff --git a/qemu-io.c b/qemu-io.c
94
+ index 9f66a78..3b5890e 100644
95
+ --- a/qemu-io.c
96
+ +++ b/qemu-io.c
97
+ @@ -33,6 +33,12 @@ static BlockDriverState *bs;
98
+
99
+ static int misalign;
100
+
101
+ +static int64_t cvtnum(const char *s)
102
+ +{
103
+ + char *end;
104
+ + return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
105
+ +}
106
+ +
107
+ /*
108
+ * Parse the pattern argument to various sub-commands.
109
+ *
110
+ --
111
+ 1.8.3.1
112
+
SOURCES/kvm-qemu-io-Move-command_loop-and-friends.patch ADDED
@@ -0,0 +1,369 @@
1
+ From 828d09abacc6ae7f0643957301cc3ddee269d7a0 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:31 +0100
4
+ Subject: [PATCH 12/27] qemu-io: Move command_loop() and friends
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-13-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68441
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 12/21] qemu-io: Move command_loop() and friends
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
+ (cherry picked from commit d1174f13e78e2f43f7ae33d59b62b0b94468c8db)
20
+ Signed-off-by: John Snow <jsnow@redhat.com>
21
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
22
+ ---
23
+ cmd.c | 139 --------------------------------------------------------------
24
+ cmd.h | 9 ----
25
+ qemu-io.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26
+ 3 files changed, 139 insertions(+), 148 deletions(-)
27
+
28
+ diff --git a/cmd.c b/cmd.c
29
+ index 6616d61..26d38a8 100644
30
+ --- a/cmd.c
31
+ +++ b/cmd.c
32
+ @@ -31,145 +31,6 @@
33
+
34
+ /* from libxcmd/command.c */
35
+
36
+ -static int ncmdline;
37
+ -static char **cmdline;
38
+ -
39
+ -
40
+ -void add_user_command(char *optarg)
41
+ -{
42
+ - cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
43
+ - cmdline[ncmdline-1] = optarg;
44
+ -}
45
+ -
46
+ -static void prep_fetchline(void *opaque)
47
+ -{
48
+ - int *fetchable = opaque;
49
+ -
50
+ - qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
51
+ - *fetchable= 1;
52
+ -}
53
+ -
54
+ -static char *get_prompt(void);
55
+ -
56
+ -void command_loop(void)
57
+ -{
58
+ - int i, done = 0, fetchable = 0, prompted = 0;
59
+ - char *input;
60
+ -
61
+ - for (i = 0; !done && i < ncmdline; i++) {
62
+ - done = qemuio_command(cmdline[i]);
63
+ - }
64
+ - if (cmdline) {
65
+ - g_free(cmdline);
66
+ - return;
67
+ - }
68
+ -
69
+ - while (!done) {
70
+ - if (!prompted) {
71
+ - printf("%s", get_prompt());
72
+ - fflush(stdout);
73
+ - qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
74
+ - prompted = 1;
75
+ - }
76
+ -
77
+ - main_loop_wait(false);
78
+ -
79
+ - if (!fetchable) {
80
+ - continue;
81
+ - }
82
+ -
83
+ - input = fetchline();
84
+ - if (input == NULL) {
85
+ - break;
86
+ - }
87
+ - done = qemuio_command(input);
88
+ - free(input);
89
+ -
90
+ - prompted = 0;
91
+ - fetchable = 0;
92
+ - }
93
+ - qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
94
+ -}
95
+ -
96
+ -/* from libxcmd/input.c */
97
+ -
98
+ -#if defined(ENABLE_READLINE)
99
+ -# include <readline/history.h>
100
+ -# include <readline/readline.h>
101
+ -#elif defined(ENABLE_EDITLINE)
102
+ -# include <histedit.h>
103
+ -#endif
104
+ -
105
+ -static char *
106
+ -get_prompt(void)
107
+ -{
108
+ - static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
109
+ -
110
+ - if (!prompt[0])
111
+ - snprintf(prompt, sizeof(prompt), "%s> ", progname);
112
+ - return prompt;
113
+ -}
114
+ -
115
+ -#if defined(ENABLE_READLINE)
116
+ -char *
117
+ -fetchline(void)
118
+ -{
119
+ - char *line;
120
+ -
121
+ - line = readline(get_prompt());
122
+ - if (line && *line)
123
+ - add_history(line);
124
+ - return line;
125
+ -}
126
+ -#elif defined(ENABLE_EDITLINE)
127
+ -static char *el_get_prompt(EditLine *e) { return get_prompt(); }
128
+ -char *
129
+ -fetchline(void)
130
+ -{
131
+ - static EditLine *el;
132
+ - static History *hist;
133
+ - HistEvent hevent;
134
+ - char *line;
135
+ - int count;
136
+ -
137
+ - if (!el) {
138
+ - hist = history_init();
139
+ - history(hist, &hevent, H_SETSIZE, 100);
140
+ - el = el_init(progname, stdin, stdout, stderr);
141
+ - el_source(el, NULL);
142
+ - el_set(el, EL_SIGNAL, 1);
143
+ - el_set(el, EL_PROMPT, el_get_prompt);
144
+ - el_set(el, EL_HIST, history, (const char *)hist);
145
+ - }
146
+ - line = strdup(el_gets(el, &count));
147
+ - if (line) {
148
+ - if (count > 0)
149
+ - line[count-1] = '\0';
150
+ - if (*line)
151
+ - history(hist, &hevent, H_ENTER, line);
152
+ - }
153
+ - return line;
154
+ -}
155
+ -#else
156
+ -# define MAXREADLINESZ 1024
157
+ -char *
158
+ -fetchline(void)
159
+ -{
160
+ - char *p, *line = malloc(MAXREADLINESZ);
161
+ -
162
+ - if (!line)
163
+ - return NULL;
164
+ - if (!fgets(line, MAXREADLINESZ, stdin)) {
165
+ - free(line);
166
+ - return NULL;
167
+ - }
168
+ - p = line + strlen(line);
169
+ - if (p != line && p[-1] == '\n')
170
+ - p[-1] = '\0';
171
+ - return line;
172
+ -}
173
+ -#endif
174
+ -
175
+ #define EXABYTES(x) ((long long)(x) << 60)
176
+ #define PETABYTES(x) ((long long)(x) << 50)
177
+ #define TERABYTES(x) ((long long)(x) << 40)
178
+ diff --git a/cmd.h b/cmd.h
179
+ index 0d01a33..da0c7cf 100644
180
+ --- a/cmd.h
181
+ +++ b/cmd.h
182
+ @@ -39,18 +39,11 @@ typedef struct cmdinfo {
183
+ helpfunc_t help;
184
+ } cmdinfo_t;
185
+
186
+ -typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
187
+ -
188
+ void qemuio_add_command(const cmdinfo_t *ci);
189
+ -void add_user_command(char *optarg);
190
+ -void add_check_command(checkfunc_t cf);
191
+
192
+ -void command_loop(void);
193
+ int qemuio_command_usage(const cmdinfo_t *ci);
194
+
195
+ /* from input.h */
196
+ -char *fetchline(void);
197
+ -
198
+ void cvtstr(double value, char *str, size_t sz);
199
+
200
+ struct timeval tsub(struct timeval t1, struct timeval t2);
201
+ @@ -64,8 +57,6 @@ enum {
202
+
203
+ void timestr(struct timeval *tv, char *str, size_t sz, int flags);
204
+
205
+ -extern char *progname;
206
+ -
207
+ bool qemuio_command(const char *cmd);
208
+
209
+ #endif /* __COMMAND_H__ */
210
+ diff --git a/qemu-io.c b/qemu-io.c
211
+ index 97af39e..da9944e 100644
212
+ --- a/qemu-io.c
213
+ +++ b/qemu-io.c
214
+ @@ -34,6 +34,10 @@ BlockDriverState *qemuio_bs;
215
+
216
+ extern int qemuio_misalign;
217
+
218
+ +/* qemu-io commands passed using -c */
219
+ +static int ncmdline;
220
+ +static char **cmdline;
221
+ +
222
+ static int close_f(BlockDriverState *bs, int argc, char **argv)
223
+ {
224
+ bdrv_unref(bs);
225
+ @@ -207,6 +211,141 @@ static void usage(const char *name)
226
+ }
227
+
228
+
229
+ +#if defined(ENABLE_READLINE)
230
+ +# include <readline/history.h>
231
+ +# include <readline/readline.h>
232
+ +#elif defined(ENABLE_EDITLINE)
233
+ +# include <histedit.h>
234
+ +#endif
235
+ +
236
+ +static char *get_prompt(void)
237
+ +{
238
+ + static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
239
+ +
240
+ + if (!prompt[0]) {
241
+ + snprintf(prompt, sizeof(prompt), "%s> ", progname);
242
+ + }
243
+ +
244
+ + return prompt;
245
+ +}
246
+ +
247
+ +#if defined(ENABLE_READLINE)
248
+ +static char *fetchline(void)
249
+ +{
250
+ + char *line = readline(get_prompt());
251
+ + if (line && *line) {
252
+ + add_history(line);
253
+ + }
254
+ + return line;
255
+ +}
256
+ +#elif defined(ENABLE_EDITLINE)
257
+ +static char *el_get_prompt(EditLine *e)
258
+ +{
259
+ + return get_prompt();
260
+ +}
261
+ +
262
+ +static char *fetchline(void)
263
+ +{
264
+ + static EditLine *el;
265
+ + static History *hist;
266
+ + HistEvent hevent;
267
+ + char *line;
268
+ + int count;
269
+ +
270
+ + if (!el) {
271
+ + hist = history_init();
272
+ + history(hist, &hevent, H_SETSIZE, 100);
273
+ + el = el_init(progname, stdin, stdout, stderr);
274
+ + el_source(el, NULL);
275
+ + el_set(el, EL_SIGNAL, 1);
276
+ + el_set(el, EL_PROMPT, el_get_prompt);
277
+ + el_set(el, EL_HIST, history, (const char *)hist);
278
+ + }
279
+ + line = strdup(el_gets(el, &count));
280
+ + if (line) {
281
+ + if (count > 0) {
282
+ + line[count-1] = '\0';
283
+ + }
284
+ + if (*line) {
285
+ + history(hist, &hevent, H_ENTER, line);
286
+ + }
287
+ + }
288
+ + return line;
289
+ +}
290
+ +#else
291
+ +# define MAXREADLINESZ 1024
292
+ +static char *fetchline(void)
293
+ +{
294
+ + char *p, *line = g_malloc(MAXREADLINESZ);
295
+ +
296
+ + if (!fgets(line, MAXREADLINESZ, stdin)) {
297
+ + g_free(line);
298
+ + return NULL;
299
+ + }
300
+ +
301
+ + p = line + strlen(line);
302
+ + if (p != line && p[-1] == '\n') {
303
+ + p[-1] = '\0';
304
+ + }
305
+ +
306
+ + return line;
307
+ +}
308
+ +#endif
309
+ +
310
+ +static void prep_fetchline(void *opaque)
311
+ +{
312
+ + int *fetchable = opaque;
313
+ +
314
+ + qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
315
+ + *fetchable= 1;
316
+ +}
317
+ +
318
+ +static void command_loop(void)
319
+ +{
320
+ + int i, done = 0, fetchable = 0, prompted = 0;
321
+ + char *input;
322
+ +
323
+ + for (i = 0; !done && i < ncmdline; i++) {
324
+ + done = qemuio_command(cmdline[i]);
325
+ + }
326
+ + if (cmdline) {
327
+ + g_free(cmdline);
328
+ + return;
329
+ + }
330
+ +
331
+ + while (!done) {
332
+ + if (!prompted) {
333
+ + printf("%s", get_prompt());
334
+ + fflush(stdout);
335
+ + qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
336
+ + prompted = 1;
337
+ + }
338
+ +
339
+ + main_loop_wait(false);
340
+ +
341
+ + if (!fetchable) {
342
+ + continue;
343
+ + }
344
+ +
345
+ + input = fetchline();
346
+ + if (input == NULL) {
347
+ + break;
348
+ + }
349
+ + done = qemuio_command(input);
350
+ + g_free(input);
351
+ +
352
+ + prompted = 0;
353
+ + fetchable = 0;
354
+ + }
355
+ + qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
356
+ +}
357
+ +
358
+ +static void add_user_command(char *optarg)
359
+ +{
360
+ + cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
361
+ + cmdline[ncmdline-1] = optarg;
362
+ +}
363
+ +
364
+ int main(int argc, char **argv)
365
+ {
366
+ int readonly = 0;
367
+ --
368
+ 1.8.3.1
369
+
SOURCES/kvm-qemu-io-Move-functions-for-registering-and-running-c.patch ADDED
@@ -0,0 +1,551 @@
1
+ From df682d833654f2f42595d6156341439644a8848d Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:30 +0100
4
+ Subject: [PATCH 11/27] qemu-io: Move functions for registering and running
5
+ commands
6
+
7
+ RH-Author: John Snow <jsnow@redhat.com>
8
+ Message-id: <1448300320-7772-12-git-send-email-jsnow@redhat.com>
9
+ Patchwork-id: 68439
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 11/21] qemu-io: Move functions for registering and running commands
11
+ Bugzilla: 1272523
12
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
15
+
16
+ From: Kevin Wolf <kwolf@redhat.com>
17
+
18
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
+ Reviewed-by: Eric Blake <eblake@redhat.com>
20
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
+ (cherry picked from commit c2cdf5c5892165cbe7d3567bff5930521bc52669)
22
+ Signed-off-by: John Snow <jsnow@redhat.com>
23
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
24
+
25
+ Conflicts:
26
+ qemu-io-cmds.c: Conflicts over sleep_f, again.
27
+
28
+ Signed-off-by: John Snow <jsnow@redhat.com>
29
+ ---
30
+ cmd.c | 113 ---------------------------------
31
+ cmd.h | 11 +---
32
+ qemu-io-cmds.c | 194 +++++++++++++++++++++++++++++++++++++++++----------------
33
+ qemu-io.c | 10 +--
34
+ 4 files changed, 149 insertions(+), 179 deletions(-)
35
+
36
+ diff --git a/cmd.c b/cmd.c
37
+ index f6bf2c5..6616d61 100644
38
+ --- a/cmd.c
39
+ +++ b/cmd.c
40
+ @@ -31,94 +31,9 @@
41
+
42
+ /* from libxcmd/command.c */
43
+
44
+ -cmdinfo_t *cmdtab;
45
+ -int ncmds;
46
+ -
47
+ -static checkfunc_t check_func;
48
+ static int ncmdline;
49
+ static char **cmdline;
50
+
51
+ -static int
52
+ -compare(const void *a, const void *b)
53
+ -{
54
+ - return strcmp(((const cmdinfo_t *)a)->name,
55
+ - ((const cmdinfo_t *)b)->name);
56
+ -}
57
+ -
58
+ -void add_command(const cmdinfo_t *ci)
59
+ -{
60
+ - cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
61
+ - cmdtab[ncmds - 1] = *ci;
62
+ - qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
63
+ -}
64
+ -
65
+ -static int
66
+ -check_command(
67
+ - const cmdinfo_t *ci)
68
+ -{
69
+ - if (check_func)
70
+ - return check_func(qemuio_bs, ci);
71
+ - return 1;
72
+ -}
73
+ -
74
+ -void
75
+ -add_check_command(
76
+ - checkfunc_t cf)
77
+ -{
78
+ - check_func = cf;
79
+ -}
80
+ -
81
+ -int
82
+ -command_usage(
83
+ - const cmdinfo_t *ci)
84
+ -{
85
+ - printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
86
+ - return 0;
87
+ -}
88
+ -
89
+ -int
90
+ -command(
91
+ - const cmdinfo_t *ct,
92
+ - int argc,
93
+ - char **argv)
94
+ -{
95
+ - char *cmd = argv[0];
96
+ -
97
+ - if (!check_command(ct))
98
+ - return 0;
99
+ -
100
+ - if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) {
101
+ - if (ct->argmax == -1)
102
+ - fprintf(stderr,
103
+ - _("bad argument count %d to %s, expected at least %d arguments\n"),
104
+ - argc-1, cmd, ct->argmin);
105
+ - else if (ct->argmin == ct->argmax)
106
+ - fprintf(stderr,
107
+ - _("bad argument count %d to %s, expected %d arguments\n"),
108
+ - argc-1, cmd, ct->argmin);
109
+ - else
110
+ - fprintf(stderr,
111
+ - _("bad argument count %d to %s, expected between %d and %d arguments\n"),
112
+ - argc-1, cmd, ct->argmin, ct->argmax);
113
+ - return 0;
114
+ - }
115
+ - optind = 0;
116
+ - return ct->cfunc(qemuio_bs, argc, argv);
117
+ -}
118
+ -
119
+ -const cmdinfo_t *
120
+ -find_command(
121
+ - const char *cmd)
122
+ -{
123
+ - cmdinfo_t *ct;
124
+ -
125
+ - for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
126
+ - if (strcmp(ct->name, cmd) == 0 ||
127
+ - (ct->altname && strcmp(ct->altname, cmd) == 0))
128
+ - return (const cmdinfo_t *)ct;
129
+ - }
130
+ - return NULL;
131
+ -}
132
+
133
+ void add_user_command(char *optarg)
134
+ {
135
+ @@ -255,34 +170,6 @@ fetchline(void)
136
+ }
137
+ #endif
138
+
139
+ -char **breakline(char *input, int *count)
140
+ -{
141
+ - int c = 0;
142
+ - char *p;
143
+ - char **rval = calloc(sizeof(char *), 1);
144
+ - char **tmp;
145
+ -
146
+ - while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
147
+ - if (!*p) {
148
+ - continue;
149
+ - }
150
+ - c++;
151
+ - tmp = realloc(rval, sizeof(*rval) * (c + 1));
152
+ - if (!tmp) {
153
+ - free(rval);
154
+ - rval = NULL;
155
+ - c = 0;
156
+ - break;
157
+ - } else {
158
+ - rval = tmp;
159
+ - }
160
+ - rval[c - 1] = p;
161
+ - rval[c] = NULL;
162
+ - }
163
+ - *count = c;
164
+ - return rval;
165
+ -}
166
+ -
167
+ #define EXABYTES(x) ((long long)(x) << 60)
168
+ #define PETABYTES(x) ((long long)(x) << 50)
169
+ #define TERABYTES(x) ((long long)(x) << 40)
170
+ diff --git a/cmd.h b/cmd.h
171
+ index 5b6f61b..0d01a33 100644
172
+ --- a/cmd.h
173
+ +++ b/cmd.h
174
+ @@ -39,23 +39,16 @@ typedef struct cmdinfo {
175
+ helpfunc_t help;
176
+ } cmdinfo_t;
177
+
178
+ -extern cmdinfo_t *cmdtab;
179
+ -extern int ncmds;
180
+ -
181
+ typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
182
+
183
+ -void add_command(const cmdinfo_t *ci);
184
+ +void qemuio_add_command(const cmdinfo_t *ci);
185
+ void add_user_command(char *optarg);
186
+ void add_check_command(checkfunc_t cf);
187
+
188
+ -const cmdinfo_t *find_command(const char *cmd);
189
+ -
190
+ void command_loop(void);
191
+ -int command_usage(const cmdinfo_t *ci);
192
+ -int command(const cmdinfo_t *ci, int argc, char **argv);
193
+ +int qemuio_command_usage(const cmdinfo_t *ci);
194
+
195
+ /* from input.h */
196
+ -char **breakline(char *input, int *count);
197
+ char *fetchline(void);
198
+
199
+ void cvtstr(double value, char *str, size_t sz);
200
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
201
+ index a8e891a..27a903f 100644
202
+ --- a/qemu-io-cmds.c
203
+ +++ b/qemu-io-cmds.c
204
+ @@ -17,6 +17,110 @@
205
+
206
+ int qemuio_misalign;
207
+
208
+ +static cmdinfo_t *cmdtab;
209
+ +static int ncmds;
210
+ +
211
+ +static int compare_cmdname(const void *a, const void *b)
212
+ +{
213
+ + return strcmp(((const cmdinfo_t *)a)->name,
214
+ + ((const cmdinfo_t *)b)->name);
215
+ +}
216
+ +
217
+ +void qemuio_add_command(const cmdinfo_t *ci)
218
+ +{
219
+ + cmdtab = g_realloc(cmdtab, ++ncmds * sizeof(*cmdtab));
220
+ + cmdtab[ncmds - 1] = *ci;
221
+ + qsort(cmdtab, ncmds, sizeof(*cmdtab), compare_cmdname);
222
+ +}
223
+ +
224
+ +int qemuio_command_usage(const cmdinfo_t *ci)
225
+ +{
226
+ + printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
227
+ + return 0;
228
+ +}
229
+ +
230
+ +static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
231
+ +{
232
+ + if (ct->flags & CMD_FLAG_GLOBAL) {
233
+ + return 1;
234
+ + }
235
+ + if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
236
+ + fprintf(stderr, "no file open, try 'help open'\n");
237
+ + return 0;
238
+ + }
239
+ + return 1;
240
+ +}
241
+ +
242
+ +static int command(const cmdinfo_t *ct, int argc, char **argv)
243
+ +{
244
+ + char *cmd = argv[0];
245
+ +
246
+ + if (!init_check_command(qemuio_bs, ct)) {
247
+ + return 0;
248
+ + }
249
+ +
250
+ + if (argc - 1 < ct->argmin || (ct->argmax != -1 && argc - 1 > ct->argmax)) {
251
+ + if (ct->argmax == -1) {
252
+ + fprintf(stderr,
253
+ + "bad argument count %d to %s, expected at least %d arguments\n",
254
+ + argc-1, cmd, ct->argmin);
255
+ + } else if (ct->argmin == ct->argmax) {
256
+ + fprintf(stderr,
257
+ + "bad argument count %d to %s, expected %d arguments\n",
258
+ + argc-1, cmd, ct->argmin);
259
+ + } else {
260
+ + fprintf(stderr,
261
+ + "bad argument count %d to %s, expected between %d and %d arguments\n",
262
+ + argc-1, cmd, ct->argmin, ct->argmax);
263
+ + }
264
+ + return 0;
265
+ + }
266
+ + optind = 0;
267
+ + return ct->cfunc(qemuio_bs, argc, argv);
268
+ +}
269
+ +
270
+ +static const cmdinfo_t *find_command(const char *cmd)
271
+ +{
272
+ + cmdinfo_t *ct;
273
+ +
274
+ + for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
275
+ + if (strcmp(ct->name, cmd) == 0 ||
276
+ + (ct->altname && strcmp(ct->altname, cmd) == 0))
277
+ + {
278
+ + return (const cmdinfo_t *)ct;
279
+ + }
280
+ + }
281
+ + return NULL;
282
+ +}
283
+ +
284
+ +static char **breakline(char *input, int *count)
285
+ +{
286
+ + int c = 0;
287
+ + char *p;
288
+ + char **rval = g_malloc0(sizeof(char *));
289
+ + char **tmp;
290
+ +
291
+ + while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
292
+ + if (!*p) {
293
+ + continue;
294
+ + }
295
+ + c++;
296
+ + tmp = g_realloc(rval, sizeof(*rval) * (c + 1));
297
+ + if (!tmp) {
298
+ + g_free(rval);
299
+ + rval = NULL;
300
+ + c = 0;
301
+ + break;
302
+ + } else {
303
+ + rval = tmp;
304
+ + }
305
+ + rval[c - 1] = p;
306
+ + rval[c] = NULL;
307
+ + }
308
+ + *count = c;
309
+ + return rval;
310
+ +}
311
+ +
312
+ static int64_t cvtnum(const char *s)
313
+ {
314
+ char *end;
315
+ @@ -468,12 +572,12 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
316
+ vflag = 1;
317
+ break;
318
+ default:
319
+ - return command_usage(&read_cmd);
320
+ + return qemuio_command_usage(&read_cmd);
321
+ }
322
+ }
323
+
324
+ if (optind != argc - 2) {
325
+ - return command_usage(&read_cmd);
326
+ + return qemuio_command_usage(&read_cmd);
327
+ }
328
+
329
+ if (bflag && pflag) {
330
+ @@ -495,7 +599,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
331
+ }
332
+
333
+ if (!Pflag && (lflag || sflag)) {
334
+ - return command_usage(&read_cmd);
335
+ + return qemuio_command_usage(&read_cmd);
336
+ }
337
+
338
+ if (!lflag) {
339
+ @@ -630,12 +734,12 @@ static int readv_f(BlockDriverState *bs, int argc, char **argv)
340
+ vflag = 1;
341
+ break;
342
+ default:
343
+ - return command_usage(&readv_cmd);
344
+ + return qemuio_command_usage(&readv_cmd);
345
+ }
346
+ }
347
+
348
+ if (optind > argc - 2) {
349
+ - return command_usage(&readv_cmd);
350
+ + return qemuio_command_usage(&readv_cmd);
351
+ }
352
+
353
+
354
+ @@ -770,12 +874,12 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
355
+ zflag = 1;
356
+ break;
357
+ default:
358
+ - return command_usage(&write_cmd);
359
+ + return qemuio_command_usage(&write_cmd);
360
+ }
361
+ }
362
+
363
+ if (optind != argc - 2) {
364
+ - return command_usage(&write_cmd);
365
+ + return qemuio_command_usage(&write_cmd);
366
+ }
367
+
368
+ if (bflag + pflag + zflag > 1) {
369
+ @@ -912,12 +1016,12 @@ static int writev_f(BlockDriverState *bs, int argc, char **argv)
370
+ }
371
+ break;
372
+ default:
373
+ - return command_usage(&writev_cmd);
374
+ + return qemuio_command_usage(&writev_cmd);
375
+ }
376
+ }
377
+
378
+ if (optind > argc - 2) {
379
+ - return command_usage(&writev_cmd);
380
+ + return qemuio_command_usage(&writev_cmd);
381
+ }
382
+
383
+ offset = cvtnum(argv[optind]);
384
+ @@ -1024,12 +1128,12 @@ static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
385
+ }
386
+ break;
387
+ default:
388
+ - return command_usage(&writev_cmd);
389
+ + return qemuio_command_usage(&writev_cmd);
390
+ }
391
+ }
392
+
393
+ if (optind > argc - 2) {
394
+ - return command_usage(&writev_cmd);
395
+ + return qemuio_command_usage(&writev_cmd);
396
+ }
397
+
398
+ nr_reqs = 1;
399
+ @@ -1258,13 +1362,13 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
400
+ break;
401
+ default:
402
+ g_free(ctx);
403
+ - return command_usage(&aio_read_cmd);
404
+ + return qemuio_command_usage(&aio_read_cmd);
405
+ }
406
+ }
407
+
408
+ if (optind > argc - 2) {
409
+ g_free(ctx);
410
+ - return command_usage(&aio_read_cmd);
411
+ + return qemuio_command_usage(&aio_read_cmd);
412
+ }
413
+
414
+ ctx->offset = cvtnum(argv[optind]);
415
+ @@ -1350,13 +1454,13 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
416
+ break;
417
+ default:
418
+ g_free(ctx);
419
+ - return command_usage(&aio_write_cmd);
420
+ + return qemuio_command_usage(&aio_write_cmd);
421
+ }
422
+ }
423
+
424
+ if (optind > argc - 2) {
425
+ g_free(ctx);
426
+ - return command_usage(&aio_write_cmd);
427
+ + return qemuio_command_usage(&aio_write_cmd);
428
+ }
429
+
430
+ ctx->offset = cvtnum(argv[optind]);
431
+ @@ -1556,12 +1660,12 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
432
+ qflag = 1;
433
+ break;
434
+ default:
435
+ - return command_usage(&discard_cmd);
436
+ + return qemuio_command_usage(&discard_cmd);
437
+ }
438
+ }
439
+
440
+ if (optind != argc - 2) {
441
+ - return command_usage(&discard_cmd);
442
+ + return qemuio_command_usage(&discard_cmd);
443
+ }
444
+
445
+ offset = cvtnum(argv[optind]);
446
+ @@ -1876,18 +1980,6 @@ static const cmdinfo_t help_cmd = {
447
+ .oneline = "help for one or all commands",
448
+ };
449
+
450
+ -static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
451
+ -{
452
+ - if (ct->flags & CMD_FLAG_GLOBAL) {
453
+ - return 1;
454
+ - }
455
+ - if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
456
+ - fprintf(stderr, "no file open, try 'help open'\n");
457
+ - return 0;
458
+ - }
459
+ - return 1;
460
+ -}
461
+ -
462
+ bool qemuio_command(const char *cmd)
463
+ {
464
+ char *input;
465
+ @@ -1915,27 +2007,25 @@ bool qemuio_command(const char *cmd)
466
+ static void __attribute((constructor)) init_qemuio_commands(void)
467
+ {
468
+ /* initialize commands */
469
+ - add_command(&help_cmd);
470
+ - add_command(&read_cmd);
471
+ - add_command(&readv_cmd);
472
+ - add_command(&write_cmd);
473
+ - add_command(&writev_cmd);
474
+ - add_command(&multiwrite_cmd);
475
+ - add_command(&aio_read_cmd);
476
+ - add_command(&aio_write_cmd);
477
+ - add_command(&aio_flush_cmd);
478
+ - add_command(&flush_cmd);
479
+ - add_command(&truncate_cmd);
480
+ - add_command(&length_cmd);
481
+ - add_command(&info_cmd);
482
+ - add_command(&discard_cmd);
483
+ - add_command(&alloc_cmd);
484
+ - add_command(&map_cmd);
485
+ - add_command(&break_cmd);
486
+ - add_command(&resume_cmd);
487
+ - add_command(&wait_break_cmd);
488
+ - add_command(&abort_cmd);
489
+ - add_command(&sleep_cmd);
490
+ -
491
+ - add_check_command(init_check_command);
492
+ + qemuio_add_command(&help_cmd);
493
+ + qemuio_add_command(&read_cmd);
494
+ + qemuio_add_command(&readv_cmd);
495
+ + qemuio_add_command(&write_cmd);
496
+ + qemuio_add_command(&writev_cmd);
497
+ + qemuio_add_command(&multiwrite_cmd);
498
+ + qemuio_add_command(&aio_read_cmd);
499
+ + qemuio_add_command(&aio_write_cmd);
500
+ + qemuio_add_command(&aio_flush_cmd);
501
+ + qemuio_add_command(&flush_cmd);
502
+ + qemuio_add_command(&truncate_cmd);
503
+ + qemuio_add_command(&length_cmd);
504
+ + qemuio_add_command(&info_cmd);
505
+ + qemuio_add_command(&discard_cmd);
506
+ + qemuio_add_command(&alloc_cmd);
507
+ + qemuio_add_command(&map_cmd);
508
+ + qemuio_add_command(&break_cmd);
509
+ + qemuio_add_command(&resume_cmd);
510
+ + qemuio_add_command(&wait_break_cmd);
511
+ + qemuio_add_command(&abort_cmd);
512
+ + qemuio_add_command(&sleep_cmd);
513
+ }
514
+ diff --git a/qemu-io.c b/qemu-io.c
515
+ index b86bfbf..97af39e 100644
516
+ --- a/qemu-io.c
517
+ +++ b/qemu-io.c
518
+ @@ -155,7 +155,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
519
+ qemu_opts_del(qopts);
520
+ break;
521
+ default:
522
+ - return command_usage(&open_cmd);
523
+ + return qemuio_command_usage(&open_cmd);
524
+ }
525
+ }
526
+
527
+ @@ -164,7 +164,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
528
+ }
529
+
530
+ if (optind != argc - 1) {
531
+ - return command_usage(&open_cmd);
532
+ + return qemuio_command_usage(&open_cmd);
533
+ }
534
+
535
+ return openfile(argv[optind], flags, growable, opts);
536
+ @@ -300,9 +300,9 @@ int main(int argc, char **argv)
537
+ bdrv_init();
538
+
539
+ /* initialize commands */
540
+ - add_command(&quit_cmd);
541
+ - add_command(&open_cmd);
542
+ - add_command(&close_cmd);
543
+ + qemuio_add_command(&quit_cmd);
544
+ + qemuio_add_command(&open_cmd);
545
+ + qemuio_add_command(&close_cmd);
546
+
547
+ /* open the device */
548
+ if (!readonly) {
549
+ --
550
+ 1.8.3.1
551
+
SOURCES/kvm-qemu-io-Move-help-function.patch ADDED
@@ -0,0 +1,223 @@
1
+ From 8d6f59c923b536461df1aea18045535b090984fb Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:27 +0100
4
+ Subject: [PATCH 08/27] qemu-io: Move 'help' function
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-9-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68435
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 08/21] qemu-io: Move 'help' function
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ No reason to treat it different from other commands. Move it to
18
+ qemu-io-cmds.c, adapt the coding style and register it like any other
19
+ command.
20
+
21
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
+ Reviewed-by: Eric Blake <eblake@redhat.com>
23
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ (cherry picked from commit f18a834a92f0b490cefeb71410f3f25b969d336f)
25
+ Signed-off-by: John Snow <jsnow@redhat.com>
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+
28
+ Conflicts:
29
+ qemu-io-cmds: patch context (from sleep_f)
30
+
31
+ Signed-off-by: John Snow <jsnow@redhat.com>
32
+ ---
33
+ cmd.c | 79 ----------------------------------------------------------
34
+ cmd.h | 1 -
35
+ qemu-io-cmds.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++-
36
+ 3 files changed, 65 insertions(+), 81 deletions(-)
37
+
38
+ diff --git a/cmd.c b/cmd.c
39
+ index 7ae978f..2941ad3 100644
40
+ --- a/cmd.c
41
+ +++ b/cmd.c
42
+ @@ -439,82 +439,3 @@ quit_init(void)
43
+
44
+ add_command(&quit_cmd);
45
+ }
46
+ -
47
+ -/* from libxcmd/help.c */
48
+ -
49
+ -static cmdinfo_t help_cmd;
50
+ -static void help_onecmd(const char *cmd, const cmdinfo_t *ct);
51
+ -static void help_oneline(const char *cmd, const cmdinfo_t *ct);
52
+ -
53
+ -static void
54
+ -help_all(void)
55
+ -{
56
+ - const cmdinfo_t *ct;
57
+ -
58
+ - for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++)
59
+ - help_oneline(ct->name, ct);
60
+ - printf(_("\nUse 'help commandname' for extended help.\n"));
61
+ -}
62
+ -
63
+ -static int
64
+ -help_f(
65
+ - BlockDriverState *bs,
66
+ - int argc,
67
+ - char **argv)
68
+ -{
69
+ - const cmdinfo_t *ct;
70
+ -
71
+ - if (argc == 1) {
72
+ - help_all();
73
+ - return 0;
74
+ - }
75
+ - ct = find_command(argv[1]);
76
+ - if (ct == NULL) {
77
+ - printf(_("command %s not found\n"), argv[1]);
78
+ - return 0;
79
+ - }
80
+ - help_onecmd(argv[1], ct);
81
+ - return 0;
82
+ -}
83
+ -
84
+ -static void
85
+ -help_onecmd(
86
+ - const char *cmd,
87
+ - const cmdinfo_t *ct)
88
+ -{
89
+ - help_oneline(cmd, ct);
90
+ - if (ct->help)
91
+ - ct->help();
92
+ -}
93
+ -
94
+ -static void
95
+ -help_oneline(
96
+ - const char *cmd,
97
+ - const cmdinfo_t *ct)
98
+ -{
99
+ - if (cmd)
100
+ - printf("%s ", cmd);
101
+ - else {
102
+ - printf("%s ", ct->name);
103
+ - if (ct->altname)
104
+ - printf("(or %s) ", ct->altname);
105
+ - }
106
+ - if (ct->args)
107
+ - printf("%s ", ct->args);
108
+ - printf("-- %s\n", ct->oneline);
109
+ -}
110
+ -
111
+ -void
112
+ -help_init(void)
113
+ -{
114
+ - help_cmd.name = _("help");
115
+ - help_cmd.altname = _("?");
116
+ - help_cmd.cfunc = help_f;
117
+ - help_cmd.argmin = 0;
118
+ - help_cmd.argmax = 1;
119
+ - help_cmd.flags = CMD_FLAG_GLOBAL;
120
+ - help_cmd.args = _("[command]");
121
+ - help_cmd.oneline = _("help for one or all commands");
122
+ -
123
+ - add_command(&help_cmd);
124
+ -}
125
+ diff --git a/cmd.h b/cmd.h
126
+ index d676408..89e7c6e 100644
127
+ --- a/cmd.h
128
+ +++ b/cmd.h
129
+ @@ -42,7 +42,6 @@ typedef struct cmdinfo {
130
+ extern cmdinfo_t *cmdtab;
131
+ extern int ncmds;
132
+
133
+ -void help_init(void);
134
+ void quit_init(void);
135
+
136
+ typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
137
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
138
+ index 09e4099..a8e891a 100644
139
+ --- a/qemu-io-cmds.c
140
+ +++ b/qemu-io-cmds.c
141
+ @@ -1811,6 +1811,70 @@ static const cmdinfo_t sleep_cmd = {
142
+ .oneline = "waits for the given value in milliseconds",
143
+ };
144
+
145
+ +static void help_oneline(const char *cmd, const cmdinfo_t *ct)
146
+ +{
147
+ + if (cmd) {
148
+ + printf("%s ", cmd);
149
+ + } else {
150
+ + printf("%s ", ct->name);
151
+ + if (ct->altname) {
152
+ + printf("(or %s) ", ct->altname);
153
+ + }
154
+ + }
155
+ +
156
+ + if (ct->args) {
157
+ + printf("%s ", ct->args);
158
+ + }
159
+ + printf("-- %s\n", ct->oneline);
160
+ +}
161
+ +
162
+ +static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
163
+ +{
164
+ + help_oneline(cmd, ct);
165
+ + if (ct->help) {
166
+ + ct->help();
167
+ + }
168
+ +}
169
+ +
170
+ +static void help_all(void)
171
+ +{
172
+ + const cmdinfo_t *ct;
173
+ +
174
+ + for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
175
+ + help_oneline(ct->name, ct);
176
+ + }
177
+ + printf("\nUse 'help commandname' for extended help.\n");
178
+ +}
179
+ +
180
+ +static int help_f(BlockDriverState *bs, int argc, char **argv)
181
+ +{
182
+ + const cmdinfo_t *ct;
183
+ +
184
+ + if (argc == 1) {
185
+ + help_all();
186
+ + return 0;
187
+ + }
188
+ +
189
+ + ct = find_command(argv[1]);
190
+ + if (ct == NULL) {
191
+ + printf("command %s not found\n", argv[1]);
192
+ + return 0;
193
+ + }
194
+ +
195
+ + help_onecmd(argv[1], ct);
196
+ + return 0;
197
+ +}
198
+ +
199
+ +static const cmdinfo_t help_cmd = {
200
+ + .name = "help",
201
+ + .altname = "?",
202
+ + .cfunc = help_f,
203
+ + .argmin = 0,
204
+ + .argmax = 1,
205
+ + .flags = CMD_FLAG_GLOBAL,
206
+ + .args = "[command]",
207
+ + .oneline = "help for one or all commands",
208
+ +};
209
+
210
+ static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
211
+ {
212
+ @@ -1851,7 +1915,7 @@ bool qemuio_command(const char *cmd)
213
+ static void __attribute((constructor)) init_qemuio_commands(void)
214
+ {
215
+ /* initialize commands */
216
+ - help_init();
217
+ + add_command(&help_cmd);
218
+ add_command(&read_cmd);
219
+ add_command(&readv_cmd);
220
+ add_command(&write_cmd);
221
+ --
222
+ 1.8.3.1
223
+
SOURCES/kvm-qemu-io-Move-qemu_strsep-to-cutils.c.patch ADDED
@@ -0,0 +1,107 @@
1
+ From 4ab2a72fcfc65bd78cf60e6e5a29e2189fddf877 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:29 +0100
4
+ Subject: [PATCH 10/27] qemu-io: Move qemu_strsep() to cutils.c
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-11-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68440
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 10/21] qemu-io: Move qemu_strsep() to cutils.c
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
+ Reviewed-by: Eric Blake <eblake@redhat.com>
19
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
+ (cherry picked from commit a38ed811474e953371f848233208c2026c2d1195)
21
+ Signed-off-by: John Snow <jsnow@redhat.com>
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+ ---
24
+ cmd.c | 21 ---------------------
25
+ include/qemu-common.h | 1 +
26
+ util/cutils.c | 21 +++++++++++++++++++++
27
+ 3 files changed, 22 insertions(+), 21 deletions(-)
28
+
29
+ diff --git a/cmd.c b/cmd.c
30
+ index 8496e74..f6bf2c5 100644
31
+ --- a/cmd.c
32
+ +++ b/cmd.c
33
+ @@ -255,27 +255,6 @@ fetchline(void)
34
+ }
35
+ #endif
36
+
37
+ -static char *qemu_strsep(char **input, const char *delim)
38
+ -{
39
+ - char *result = *input;
40
+ - if (result != NULL) {
41
+ - char *p;
42
+ -
43
+ - for (p = result; *p != '\0'; p++) {
44
+ - if (strchr(delim, *p)) {
45
+ - break;
46
+ - }
47
+ - }
48
+ - if (*p == '\0') {
49
+ - *input = NULL;
50
+ - } else {
51
+ - *p = '\0';
52
+ - *input = p + 1;
53
+ - }
54
+ - }
55
+ - return result;
56
+ -}
57
+ -
58
+ char **breakline(char *input, int *count)
59
+ {
60
+ int c = 0;
61
+ diff --git a/include/qemu-common.h b/include/qemu-common.h
62
+ index 67f57c9..8c1132c 100644
63
+ --- a/include/qemu-common.h
64
+ +++ b/include/qemu-common.h
65
+ @@ -161,6 +161,7 @@ char *pstrcat(char *buf, int buf_size, const char *s);
66
+ int strstart(const char *str, const char *val, const char **ptr);
67
+ int stristart(const char *str, const char *val, const char **ptr);
68
+ int qemu_strnlen(const char *s, int max_len);
69
+ +char *qemu_strsep(char **input, const char *delim);
70
+ time_t mktimegm(struct tm *tm);
71
+ int qemu_fls(int i);
72
+ int qemu_fdatasync(int fd);
73
+ diff --git a/util/cutils.c b/util/cutils.c
74
+ index 8f28896..0116fcd 100644
75
+ --- a/util/cutils.c
76
+ +++ b/util/cutils.c
77
+ @@ -107,6 +107,27 @@ int qemu_strnlen(const char *s, int max_len)
78
+ return i;
79
+ }
80
+
81
+ +char *qemu_strsep(char **input, const char *delim)
82
+ +{
83
+ + char *result = *input;
84
+ + if (result != NULL) {
85
+ + char *p;
86
+ +
87
+ + for (p = result; *p != '\0'; p++) {
88
+ + if (strchr(delim, *p)) {
89
+ + break;
90
+ + }
91
+ + }
92
+ + if (*p == '\0') {
93
+ + *input = NULL;
94
+ + } else {
95
+ + *p = '\0';
96
+ + *input = p + 1;
97
+ + }
98
+ + }
99
+ + return result;
100
+ +}
101
+ +
102
+ time_t mktimegm(struct tm *tm)
103
+ {
104
+ time_t t;
105
+ --
106
+ 1.8.3.1
107
+
SOURCES/kvm-qemu-io-Move-quit-function.patch ADDED
@@ -0,0 +1,119 @@
1
+ From 6ea43a1599b4abdfe480d6e963dbbafa9339601a Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:28 +0100
4
+ Subject: [PATCH 09/27] qemu-io: Move 'quit' function
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-10-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68436
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 09/21] qemu-io: Move 'quit' function
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ This one only makes sense in the context of the qemu-io tool, so move it
18
+ to qemu-io.c. Adapt coding style and register it like other commands.
19
+
20
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
+ Reviewed-by: Eric Blake <eblake@redhat.com>
22
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
23
+ (cherry picked from commit e681be7eca0143fe7259ce8233fe5dd8898d072f)
24
+ Signed-off-by: John Snow <jsnow@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ cmd.c | 29 -----------------------------
28
+ cmd.h | 2 --
29
+ qemu-io.c | 17 ++++++++++++++++-
30
+ 3 files changed, 16 insertions(+), 32 deletions(-)
31
+
32
+ diff --git a/cmd.c b/cmd.c
33
+ index 2941ad3..8496e74 100644
34
+ --- a/cmd.c
35
+ +++ b/cmd.c
36
+ @@ -410,32 +410,3 @@ timestr(
37
+ snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
38
+ }
39
+ }
40
+ -
41
+ -
42
+ -/* from libxcmd/quit.c */
43
+ -
44
+ -static cmdinfo_t quit_cmd;
45
+ -
46
+ -/* ARGSUSED */
47
+ -static int
48
+ -quit_f(
49
+ - BlockDriverState *bs,
50
+ - int argc,
51
+ - char **argv)
52
+ -{
53
+ - return 1;
54
+ -}
55
+ -
56
+ -void
57
+ -quit_init(void)
58
+ -{
59
+ - quit_cmd.name = _("quit");
60
+ - quit_cmd.altname = _("q");
61
+ - quit_cmd.cfunc = quit_f;
62
+ - quit_cmd.argmin = -1;
63
+ - quit_cmd.argmax = -1;
64
+ - quit_cmd.flags = CMD_FLAG_GLOBAL;
65
+ - quit_cmd.oneline = _("exit the program");
66
+ -
67
+ - add_command(&quit_cmd);
68
+ -}
69
+ diff --git a/cmd.h b/cmd.h
70
+ index 89e7c6e..5b6f61b 100644
71
+ --- a/cmd.h
72
+ +++ b/cmd.h
73
+ @@ -42,8 +42,6 @@ typedef struct cmdinfo {
74
+ extern cmdinfo_t *cmdtab;
75
+ extern int ncmds;
76
+
77
+ -void quit_init(void);
78
+ -
79
+ typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
80
+
81
+ void add_command(const cmdinfo_t *ci);
82
+ diff --git a/qemu-io.c b/qemu-io.c
83
+ index 4f1c808..b86bfbf 100644
84
+ --- a/qemu-io.c
85
+ +++ b/qemu-io.c
86
+ @@ -170,6 +170,21 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
87
+ return openfile(argv[optind], flags, growable, opts);
88
+ }
89
+
90
+ +static int quit_f(BlockDriverState *bs, int argc, char **argv)
91
+ +{
92
+ + return 1;
93
+ +}
94
+ +
95
+ +static const cmdinfo_t quit_cmd = {
96
+ + .name = "quit",
97
+ + .altname = "q",
98
+ + .cfunc = quit_f,
99
+ + .argmin = -1,
100
+ + .argmax = -1,
101
+ + .flags = CMD_FLAG_GLOBAL,
102
+ + .oneline = "exit the program",
103
+ +};
104
+ +
105
+ static void usage(const char *name)
106
+ {
107
+ printf(
108
+ @@ -285,7 +300,7 @@ int main(int argc, char **argv)
109
+ bdrv_init();
110
+
111
+ /* initialize commands */
112
+ - quit_init();
113
+ + add_command(&quit_cmd);
114
+ add_command(&open_cmd);
115
+ add_command(&close_cmd);
116
+
117
+ --
118
+ 1.8.3.1
119
+
SOURCES/kvm-qemu-io-Move-remaining-helpers-from-cmd.c.patch ADDED
@@ -0,0 +1,330 @@
1
+ From f0e4ec43a0a3af6f1e385fae17527ed76cdb00e4 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:32 +0100
4
+ Subject: [PATCH 13/27] qemu-io: Move remaining helpers from cmd.c
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-14-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68437
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 13/21] qemu-io: Move remaining helpers from cmd.c
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
+ (cherry picked from commit 0b613881ae8fc59359b3d91e666fea6c9b1e731b)
20
+ Signed-off-by: John Snow <jsnow@redhat.com>
21
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
22
+ ---
23
+ Makefile | 2 +-
24
+ cmd.c | 139 ---------------------------------------------------------
25
+ cmd.h | 14 ------
26
+ qemu-io-cmds.c | 104 ++++++++++++++++++++++++++++++++++++++++++
27
+ 4 files changed, 105 insertions(+), 154 deletions(-)
28
+ delete mode 100644 cmd.c
29
+
30
+ diff --git a/Makefile b/Makefile
31
+ index f28ce29..f403057 100644
32
+ --- a/Makefile
33
+ +++ b/Makefile
34
+ @@ -205,7 +205,7 @@ qemu-img.o: qemu-img-cmds.h
35
+
36
+ qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
37
+ qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
38
+ -qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
39
+ +qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o $(block-obj-y) libqemuutil.a libqemustub.a
40
+
41
+ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
42
+
43
+ diff --git a/cmd.c b/cmd.c
44
+ deleted file mode 100644
45
+ index 26d38a8..0000000
46
+ --- a/cmd.c
47
+ +++ /dev/null
48
+ @@ -1,139 +0,0 @@
49
+ -/*
50
+ - * Copyright (c) 2003-2005 Silicon Graphics, Inc.
51
+ - * All Rights Reserved.
52
+ - *
53
+ - * This program is free software; you can redistribute it and/or
54
+ - * modify it under the terms of the GNU General Public License as
55
+ - * published by the Free Software Foundation.
56
+ - *
57
+ - * This program is distributed in the hope that it would be useful,
58
+ - * but WITHOUT ANY WARRANTY; without even the implied warranty of
59
+ - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60
+ - * GNU General Public License for more details.
61
+ - *
62
+ - * You should have received a copy of the GNU General Public License
63
+ - * along with this program; if not, see <http://www.gnu.org/licenses/>.
64
+ - */
65
+ -
66
+ -#include <stdio.h>
67
+ -#include <stdlib.h>
68
+ -#include <string.h>
69
+ -#include <ctype.h>
70
+ -#include <errno.h>
71
+ -#include <sys/time.h>
72
+ -#include <getopt.h>
73
+ -
74
+ -#include "cmd.h"
75
+ -#include "block/aio.h"
76
+ -#include "qemu/main-loop.h"
77
+ -
78
+ -#define _(x) x /* not gettext support yet */
79
+ -
80
+ -/* from libxcmd/command.c */
81
+ -
82
+ -#define EXABYTES(x) ((long long)(x) << 60)
83
+ -#define PETABYTES(x) ((long long)(x) << 50)
84
+ -#define TERABYTES(x) ((long long)(x) << 40)
85
+ -#define GIGABYTES(x) ((long long)(x) << 30)
86
+ -#define MEGABYTES(x) ((long long)(x) << 20)
87
+ -#define KILOBYTES(x) ((long long)(x) << 10)
88
+ -
89
+ -#define TO_EXABYTES(x) ((x) / EXABYTES(1))
90
+ -#define TO_PETABYTES(x) ((x) / PETABYTES(1))
91
+ -#define TO_TERABYTES(x) ((x) / TERABYTES(1))
92
+ -#define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
93
+ -#define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
94
+ -#define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
95
+ -
96
+ -void
97
+ -cvtstr(
98
+ - double value,
99
+ - char *str,
100
+ - size_t size)
101
+ -{
102
+ - char *trim;
103
+ - const char *suffix;
104
+ -
105
+ - if (value >= EXABYTES(1)) {
106
+ - suffix = " EiB";
107
+ - snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
108
+ - } else if (value >= PETABYTES(1)) {
109
+ - suffix = " PiB";
110
+ - snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
111
+ - } else if (value >= TERABYTES(1)) {
112
+ - suffix = " TiB";
113
+ - snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
114
+ - } else if (value >= GIGABYTES(1)) {
115
+ - suffix = " GiB";
116
+ - snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
117
+ - } else if (value >= MEGABYTES(1)) {
118
+ - suffix = " MiB";
119
+ - snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
120
+ - } else if (value >= KILOBYTES(1)) {
121
+ - suffix = " KiB";
122
+ - snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
123
+ - } else {
124
+ - suffix = " bytes";
125
+ - snprintf(str, size - 6, "%f", value);
126
+ - }
127
+ -
128
+ - trim = strstr(str, ".000");
129
+ - if (trim) {
130
+ - strcpy(trim, suffix);
131
+ - } else {
132
+ - strcat(str, suffix);
133
+ - }
134
+ -}
135
+ -
136
+ -struct timeval
137
+ -tsub(struct timeval t1, struct timeval t2)
138
+ -{
139
+ - t1.tv_usec -= t2.tv_usec;
140
+ - if (t1.tv_usec < 0) {
141
+ - t1.tv_usec += 1000000;
142
+ - t1.tv_sec--;
143
+ - }
144
+ - t1.tv_sec -= t2.tv_sec;
145
+ - return t1;
146
+ -}
147
+ -
148
+ -double
149
+ -tdiv(double value, struct timeval tv)
150
+ -{
151
+ - return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
152
+ -}
153
+ -
154
+ -#define HOURS(sec) ((sec) / (60 * 60))
155
+ -#define MINUTES(sec) (((sec) % (60 * 60)) / 60)
156
+ -#define SECONDS(sec) ((sec) % 60)
157
+ -
158
+ -void
159
+ -timestr(
160
+ - struct timeval *tv,
161
+ - char *ts,
162
+ - size_t size,
163
+ - int format)
164
+ -{
165
+ - double usec = (double)tv->tv_usec / 1000000.0;
166
+ -
167
+ - if (format & TERSE_FIXED_TIME) {
168
+ - if (!HOURS(tv->tv_sec)) {
169
+ - snprintf(ts, size, "%u:%02u.%02u",
170
+ - (unsigned int) MINUTES(tv->tv_sec),
171
+ - (unsigned int) SECONDS(tv->tv_sec),
172
+ - (unsigned int) (usec * 100));
173
+ - return;
174
+ - }
175
+ - format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
176
+ - }
177
+ -
178
+ - if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
179
+ - snprintf(ts, size, "%u:%02u:%02u.%02u",
180
+ - (unsigned int) HOURS(tv->tv_sec),
181
+ - (unsigned int) MINUTES(tv->tv_sec),
182
+ - (unsigned int) SECONDS(tv->tv_sec),
183
+ - (unsigned int) (usec * 100));
184
+ - } else {
185
+ - snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
186
+ - }
187
+ -}
188
+ diff --git a/cmd.h b/cmd.h
189
+ index da0c7cf..9907795 100644
190
+ --- a/cmd.h
191
+ +++ b/cmd.h
192
+ @@ -43,20 +43,6 @@ void qemuio_add_command(const cmdinfo_t *ci);
193
+
194
+ int qemuio_command_usage(const cmdinfo_t *ci);
195
+
196
+ -/* from input.h */
197
+ -void cvtstr(double value, char *str, size_t sz);
198
+ -
199
+ -struct timeval tsub(struct timeval t1, struct timeval t2);
200
+ -double tdiv(double value, struct timeval tv);
201
+ -
202
+ -enum {
203
+ - DEFAULT_TIME = 0x0,
204
+ - TERSE_FIXED_TIME = 0x1,
205
+ - VERBOSE_FIXED_TIME = 0x2
206
+ -};
207
+ -
208
+ -void timestr(struct timeval *tv, char *str, size_t sz, int flags);
209
+ -
210
+ bool qemuio_command(const char *cmd);
211
+
212
+ #endif /* __COMMAND_H__ */
213
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
214
+ index 27a903f..1db7fb9 100644
215
+ --- a/qemu-io-cmds.c
216
+ +++ b/qemu-io-cmds.c
217
+ @@ -127,6 +127,110 @@ static int64_t cvtnum(const char *s)
218
+ return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
219
+ }
220
+
221
+ +#define EXABYTES(x) ((long long)(x) << 60)
222
+ +#define PETABYTES(x) ((long long)(x) << 50)
223
+ +#define TERABYTES(x) ((long long)(x) << 40)
224
+ +#define GIGABYTES(x) ((long long)(x) << 30)
225
+ +#define MEGABYTES(x) ((long long)(x) << 20)
226
+ +#define KILOBYTES(x) ((long long)(x) << 10)
227
+ +
228
+ +#define TO_EXABYTES(x) ((x) / EXABYTES(1))
229
+ +#define TO_PETABYTES(x) ((x) / PETABYTES(1))
230
+ +#define TO_TERABYTES(x) ((x) / TERABYTES(1))
231
+ +#define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
232
+ +#define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
233
+ +#define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
234
+ +
235
+ +static void cvtstr(double value, char *str, size_t size)
236
+ +{
237
+ + char *trim;
238
+ + const char *suffix;
239
+ +
240
+ + if (value >= EXABYTES(1)) {
241
+ + suffix = " EiB";
242
+ + snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
243
+ + } else if (value >= PETABYTES(1)) {
244
+ + suffix = " PiB";
245
+ + snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
246
+ + } else if (value >= TERABYTES(1)) {
247
+ + suffix = " TiB";
248
+ + snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
249
+ + } else if (value >= GIGABYTES(1)) {
250
+ + suffix = " GiB";
251
+ + snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
252
+ + } else if (value >= MEGABYTES(1)) {
253
+ + suffix = " MiB";
254
+ + snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
255
+ + } else if (value >= KILOBYTES(1)) {
256
+ + suffix = " KiB";
257
+ + snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
258
+ + } else {
259
+ + suffix = " bytes";
260
+ + snprintf(str, size - 6, "%f", value);
261
+ + }
262
+ +
263
+ + trim = strstr(str, ".000");
264
+ + if (trim) {
265
+ + strcpy(trim, suffix);
266
+ + } else {
267
+ + strcat(str, suffix);
268
+ + }
269
+ +}
270
+ +
271
+ +
272
+ +
273
+ +static struct timeval tsub(struct timeval t1, struct timeval t2)
274
+ +{
275
+ + t1.tv_usec -= t2.tv_usec;
276
+ + if (t1.tv_usec < 0) {
277
+ + t1.tv_usec += 1000000;
278
+ + t1.tv_sec--;
279
+ + }
280
+ + t1.tv_sec -= t2.tv_sec;
281
+ + return t1;
282
+ +}
283
+ +
284
+ +static double tdiv(double value, struct timeval tv)
285
+ +{
286
+ + return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
287
+ +}
288
+ +
289
+ +#define HOURS(sec) ((sec) / (60 * 60))
290
+ +#define MINUTES(sec) (((sec) % (60 * 60)) / 60)
291
+ +#define SECONDS(sec) ((sec) % 60)
292
+ +
293
+ +enum {
294
+ + DEFAULT_TIME = 0x0,
295
+ + TERSE_FIXED_TIME = 0x1,
296
+ + VERBOSE_FIXED_TIME = 0x2,
297
+ +};
298
+ +
299
+ +static void timestr(struct timeval *tv, char *ts, size_t size, int format)
300
+ +{
301
+ + double usec = (double)tv->tv_usec / 1000000.0;
302
+ +
303
+ + if (format & TERSE_FIXED_TIME) {
304
+ + if (!HOURS(tv->tv_sec)) {
305
+ + snprintf(ts, size, "%u:%02u.%02u",
306
+ + (unsigned int) MINUTES(tv->tv_sec),
307
+ + (unsigned int) SECONDS(tv->tv_sec),
308
+ + (unsigned int) (usec * 100));
309
+ + return;
310
+ + }
311
+ + format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
312
+ + }
313
+ +
314
+ + if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
315
+ + snprintf(ts, size, "%u:%02u:%02u.%02u",
316
+ + (unsigned int) HOURS(tv->tv_sec),
317
+ + (unsigned int) MINUTES(tv->tv_sec),
318
+ + (unsigned int) SECONDS(tv->tv_sec),
319
+ + (unsigned int) (usec * 100));
320
+ + } else {
321
+ + snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
322
+ + }
323
+ +}
324
+ +
325
+ /*
326
+ * Parse the pattern argument to various sub-commands.
327
+ *
328
+ --
329
+ 1.8.3.1
330
+
SOURCES/kvm-qemu-io-Remove-unused-args_command.patch ADDED
@@ -0,0 +1,141 @@
1
+ From d16c34d6dc39a159326efda97101aed3c1481812 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:20 +0100
4
+ Subject: [PATCH 01/27] qemu-io: Remove unused args_command
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-2-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68429
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 01/21] qemu-io: Remove unused args_command
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ The original intention seems to be something with handling multiple
18
+ images at once, but this has never been implemented and the only
19
+ function ever registered is implemented to make everything behave like a
20
+ "global" command. Just do that unconditionally now.
21
+
22
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
+ Reviewed-by: Eric Blake <eblake@redhat.com>
24
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
25
+ (cherry picked from commit a23818f4ff3d7981f49453b739f589e4205930b5)
26
+ Signed-off-by: John Snow <jsnow@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+ ---
29
+ cmd.c | 28 ++--------------------------
30
+ cmd.h | 2 --
31
+ qemu-io.c | 10 ----------
32
+ 3 files changed, 2 insertions(+), 38 deletions(-)
33
+
34
+ diff --git a/cmd.c b/cmd.c
35
+ index 10a8688..4e7579b 100644
36
+ --- a/cmd.c
37
+ +++ b/cmd.c
38
+ @@ -34,7 +34,6 @@
39
+ cmdinfo_t *cmdtab;
40
+ int ncmds;
41
+
42
+ -static argsfunc_t args_func;
43
+ static checkfunc_t check_func;
44
+ static int ncmdline;
45
+ static char **cmdline;
46
+ @@ -127,22 +126,6 @@ void add_user_command(char *optarg)
47
+ cmdline[ncmdline-1] = optarg;
48
+ }
49
+
50
+ -static int
51
+ -args_command(
52
+ - int index)
53
+ -{
54
+ - if (args_func)
55
+ - return args_func(index);
56
+ - return 0;
57
+ -}
58
+ -
59
+ -void
60
+ -add_args_command(
61
+ - argsfunc_t af)
62
+ -{
63
+ - args_func = af;
64
+ -}
65
+ -
66
+ static void prep_fetchline(void *opaque)
67
+ {
68
+ int *fetchable = opaque;
69
+ @@ -155,7 +138,7 @@ static char *get_prompt(void);
70
+
71
+ void command_loop(void)
72
+ {
73
+ - int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
74
+ + int c, i, done = 0, fetchable = 0, prompted = 0;
75
+ char *input;
76
+ char **v;
77
+ const cmdinfo_t *ct;
78
+ @@ -171,14 +154,7 @@ void command_loop(void)
79
+ if (c) {
80
+ ct = find_command(v[0]);
81
+ if (ct) {
82
+ - if (ct->flags & CMD_FLAG_GLOBAL) {
83
+ - done = command(ct, c, v);
84
+ - } else {
85
+ - j = 0;
86
+ - while (!done && (j = args_command(j))) {
87
+ - done = command(ct, c, v);
88
+ - }
89
+ - }
90
+ + done = command(ct, c, v);
91
+ } else {
92
+ fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
93
+ }
94
+ diff --git a/cmd.h b/cmd.h
95
+ index b763b19..8e6f753 100644
96
+ --- a/cmd.h
97
+ +++ b/cmd.h
98
+ @@ -41,12 +41,10 @@ extern int ncmds;
99
+ void help_init(void);
100
+ void quit_init(void);
101
+
102
+ -typedef int (*argsfunc_t)(int index);
103
+ typedef int (*checkfunc_t)(const cmdinfo_t *ci);
104
+
105
+ void add_command(const cmdinfo_t *ci);
106
+ void add_user_command(char *optarg);
107
+ -void add_args_command(argsfunc_t af);
108
+ void add_check_command(checkfunc_t cf);
109
+
110
+ const cmdinfo_t *find_command(const char *cmd);
111
+ diff --git a/qemu-io.c b/qemu-io.c
112
+ index cc89947..9f66a78 100644
113
+ --- a/qemu-io.c
114
+ +++ b/qemu-io.c
115
+ @@ -1935,15 +1935,6 @@ static int open_f(int argc, char **argv)
116
+ return openfile(argv[optind], flags, growable, opts);
117
+ }
118
+
119
+ -static int init_args_command(int index)
120
+ -{
121
+ - /* only one device allowed so far */
122
+ - if (index >= 1) {
123
+ - return 0;
124
+ - }
125
+ - return ++index;
126
+ -}
127
+ -
128
+ static int init_check_command(const cmdinfo_t *ct)
129
+ {
130
+ if (ct->flags & CMD_FLAG_GLOBAL) {
131
+ @@ -2096,7 +2087,6 @@ int main(int argc, char **argv)
132
+ add_command(&abort_cmd);
133
+ add_command(&sleep_cmd);
134
+
135
+ - add_args_command(init_args_command);
136
+ add_check_command(init_check_command);
137
+
138
+ /* open the device */
139
+ --
140
+ 1.8.3.1
141
+
SOURCES/kvm-qemu-io-Split-off-commands-to-qemu-io-cmds.c.patch ADDED
@@ -0,0 +1,3789 @@
1
+ From 9bd448e0f256ac9327363a0f370b9616d967e986 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:25 +0100
4
+ Subject: [PATCH 06/27] qemu-io: Split off commands to qemu-io-cmds.c
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-7-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68434
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 06/21] qemu-io: Split off commands to qemu-io-cmds.c
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ This is the implementation of all qemu-io commands that make sense to be
18
+ called from the qemu monitor, i.e. everything except open, close and
19
+ quit.
20
+
21
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
+ Reviewed-by: Eric Blake <eblake@redhat.com>
23
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ (cherry picked from commit 797ac58cb2093ab9192d8998a1fef85d87cc8661)
25
+ Signed-off-by: John Snow <jsnow@redhat.com>
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+
28
+ Conflicts:
29
+ qemu-io.c: Minor differences, but as this is code motion,
30
+ The code motion had to be re-done to preserve
31
+ any backported changes.
32
+ qemu-io-cmds.c: re-created from downstream qemu-io.c.
33
+
34
+ Signed-off-by: John Snow <jsnow@redhat.com>
35
+ ---
36
+ Makefile | 2 +-
37
+ qemu-io-cmds.c | 1853 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
38
+ qemu-io.c | 1831 +------------------------------------------------------
39
+ 3 files changed, 1856 insertions(+), 1830 deletions(-)
40
+ create mode 100644 qemu-io-cmds.c
41
+
42
+ diff --git a/Makefile b/Makefile
43
+ index 8407945..f28ce29 100644
44
+ --- a/Makefile
45
+ +++ b/Makefile
46
+ @@ -205,7 +205,7 @@ qemu-img.o: qemu-img-cmds.h
47
+
48
+ qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
49
+ qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
50
+ -qemu-io$(EXESUF): qemu-io.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
51
+ +qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
52
+
53
+ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
54
+
55
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
56
+ new file mode 100644
57
+ index 0000000..efa6070
58
+ --- /dev/null
59
+ +++ b/qemu-io-cmds.c
60
+ @@ -0,0 +1,1853 @@
61
+ +/*
62
+ + * Command line utility to exercise the QEMU I/O path.
63
+ + *
64
+ + * Copyright (C) 2009 Red Hat, Inc.
65
+ + * Copyright (c) 2003-2005 Silicon Graphics, Inc.
66
+ + *
67
+ + * This work is licensed under the terms of the GNU GPL, version 2 or later.
68
+ + * See the COPYING file in the top-level directory.
69
+ + */
70
+ +
71
+ +#include "qemu-common.h"
72
+ +#include "block/block_int.h"
73
+ +#include "block/qapi.h"
74
+ +#include "cmd.h"
75
+ +
76
+ +#define CMD_NOFILE_OK 0x01
77
+ +
78
+ +int qemuio_misalign;
79
+ +
80
+ +static int64_t cvtnum(const char *s)
81
+ +{
82
+ + char *end;
83
+ + return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
84
+ +}
85
+ +
86
+ +/*
87
+ + * Parse the pattern argument to various sub-commands.
88
+ + *
89
+ + * Because the pattern is used as an argument to memset it must evaluate
90
+ + * to an unsigned integer that fits into a single byte.
91
+ + */
92
+ +static int parse_pattern(const char *arg)
93
+ +{
94
+ + char *endptr = NULL;
95
+ + long pattern;
96
+ +
97
+ + pattern = strtol(arg, &endptr, 0);
98
+ + if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
99
+ + printf("%s is not a valid pattern byte\n", arg);
100
+ + return -1;
101
+ + }
102
+ +
103
+ + return pattern;
104
+ +}
105
+ +
106
+ +/*
107
+ + * Memory allocation helpers.
108
+ + *
109
+ + * Make sure memory is aligned by default, or purposefully misaligned if
110
+ + * that is specified on the command line.
111
+ + */
112
+ +
113
+ +#define MISALIGN_OFFSET 16
114
+ +static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
115
+ +{
116
+ + void *buf;
117
+ +
118
+ + if (qemuio_misalign) {
119
+ + len += MISALIGN_OFFSET;
120
+ + }
121
+ + buf = qemu_blockalign(bs, len);
122
+ + memset(buf, pattern, len);
123
+ + if (qemuio_misalign) {
124
+ + buf += MISALIGN_OFFSET;
125
+ + }
126
+ + return buf;
127
+ +}
128
+ +
129
+ +static void qemu_io_free(void *p)
130
+ +{
131
+ + if (qemuio_misalign) {
132
+ + p -= MISALIGN_OFFSET;
133
+ + }
134
+ + qemu_vfree(p);
135
+ +}
136
+ +
137
+ +static void dump_buffer(const void *buffer, int64_t offset, int len)
138
+ +{
139
+ + int i, j;
140
+ + const uint8_t *p;
141
+ +
142
+ + for (i = 0, p = buffer; i < len; i += 16) {
143
+ + const uint8_t *s = p;
144
+ +
145
+ + printf("%08" PRIx64 ": ", offset + i);
146
+ + for (j = 0; j < 16 && i + j < len; j++, p++) {
147
+ + printf("%02x ", *p);
148
+ + }
149
+ + printf(" ");
150
+ + for (j = 0; j < 16 && i + j < len; j++, s++) {
151
+ + if (isalnum(*s)) {
152
+ + printf("%c", *s);
153
+ + } else {
154
+ + printf(".");
155
+ + }
156
+ + }
157
+ + printf("\n");
158
+ + }
159
+ +}
160
+ +
161
+ +static void print_report(const char *op, struct timeval *t, int64_t offset,
162
+ + int count, int total, int cnt, int Cflag)
163
+ +{
164
+ + char s1[64], s2[64], ts[64];
165
+ +
166
+ + timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
167
+ + if (!Cflag) {
168
+ + cvtstr((double)total, s1, sizeof(s1));
169
+ + cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
170
+ + printf("%s %d/%d bytes at offset %" PRId64 "\n",
171
+ + op, total, count, offset);
172
+ + printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
173
+ + s1, cnt, ts, s2, tdiv((double)cnt, *t));
174
+ + } else {/* bytes,ops,time,bytes/sec,ops/sec */
175
+ + printf("%d,%d,%s,%.3f,%.3f\n",
176
+ + total, cnt, ts,
177
+ + tdiv((double)total, *t),
178
+ + tdiv((double)cnt, *t));
179
+ + }
180
+ +}
181
+ +
182
+ +/*
183
+ + * Parse multiple length statements for vectored I/O, and construct an I/O
184
+ + * vector matching it.
185
+ + */
186
+ +static void *
187
+ +create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
188
+ + int pattern)
189
+ +{
190
+ + size_t *sizes = g_new0(size_t, nr_iov);
191
+ + size_t count = 0;
192
+ + void *buf = NULL;
193
+ + void *p;
194
+ + int i;
195
+ +
196
+ + for (i = 0; i < nr_iov; i++) {
197
+ + char *arg = argv[i];
198
+ + int64_t len;
199
+ +
200
+ + len = cvtnum(arg);
201
+ + if (len < 0) {
202
+ + printf("non-numeric length argument -- %s\n", arg);
203
+ + goto fail;
204
+ + }
205
+ +
206
+ + /* should be SIZE_T_MAX, but that doesn't exist */
207
+ + if (len > INT_MAX) {
208
+ + printf("too large length argument -- %s\n", arg);
209
+ + goto fail;
210
+ + }
211
+ +
212
+ + if (len & 0x1ff) {
213
+ + printf("length argument %" PRId64
214
+ + " is not sector aligned\n", len);
215
+ + goto fail;
216
+ + }
217
+ +
218
+ + sizes[i] = len;
219
+ + count += len;
220
+ + }
221
+ +
222
+ + qemu_iovec_init(qiov, nr_iov);
223
+ +
224
+ + buf = p = qemu_io_alloc(bs, count, pattern);
225
+ +
226
+ + for (i = 0; i < nr_iov; i++) {
227
+ + qemu_iovec_add(qiov, p, sizes[i]);
228
+ + p += sizes[i];
229
+ + }
230
+ +
231
+ +fail:
232
+ + g_free(sizes);
233
+ + return buf;
234
+ +}
235
+ +
236
+ +static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
237
+ + int *total)
238
+ +{
239
+ + int ret;
240
+ +
241
+ + ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
242
+ + if (ret < 0) {
243
+ + return ret;
244
+ + }
245
+ + *total = count;
246
+ + return 1;
247
+ +}
248
+ +
249
+ +static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
250
+ + int *total)
251
+ +{
252
+ + int ret;
253
+ +
254
+ + ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
255
+ + if (ret < 0) {
256
+ + return ret;
257
+ + }
258
+ + *total = count;
259
+ + return 1;
260
+ +}
261
+ +
262
+ +static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
263
+ + int *total)
264
+ +{
265
+ + *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
266
+ + if (*total < 0) {
267
+ + return *total;
268
+ + }
269
+ + return 1;
270
+ +}
271
+ +
272
+ +static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
273
+ + int *total)
274
+ +{
275
+ + *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
276
+ + if (*total < 0) {
277
+ + return *total;
278
+ + }
279
+ + return 1;
280
+ +}
281
+ +
282
+ +typedef struct {
283
+ + BlockDriverState *bs;
284
+ + int64_t offset;
285
+ + int count;
286
+ + int *total;
287
+ + int ret;
288
+ + bool done;
289
+ +} CoWriteZeroes;
290
+ +
291
+ +static void coroutine_fn co_write_zeroes_entry(void *opaque)
292
+ +{
293
+ + CoWriteZeroes *data = opaque;
294
+ +
295
+ + data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
296
+ + data->count / BDRV_SECTOR_SIZE, 0);
297
+ + data->done = true;
298
+ + if (data->ret < 0) {
299
+ + *data->total = data->ret;
300
+ + return;
301
+ + }
302
+ +
303
+ + *data->total = data->count;
304
+ +}
305
+ +
306
+ +static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
307
+ + int *total)
308
+ +{
309
+ + Coroutine *co;
310
+ + CoWriteZeroes data = {
311
+ + .bs = bs,
312
+ + .offset = offset,
313
+ + .count = count,
314
+ + .total = total,
315
+ + .done = false,
316
+ + };
317
+ +
318
+ + co = qemu_coroutine_create(co_write_zeroes_entry);
319
+ + qemu_coroutine_enter(co, &data);
320
+ + while (!data.done) {
321
+ + qemu_aio_wait();
322
+ + }
323
+ + if (data.ret < 0) {
324
+ + return data.ret;
325
+ + } else {
326
+ + return 1;
327
+ + }
328
+ +}
329
+ +
330
+ +static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
331
+ + int count, int *total)
332
+ +{
333
+ + int ret;
334
+ +
335
+ + ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
336
+ + if (ret < 0) {
337
+ + return ret;
338
+ + }
339
+ + *total = count;
340
+ + return 1;
341
+ +}
342
+ +
343
+ +static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
344
+ + int count, int *total)
345
+ +{
346
+ + *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
347
+ + if (*total < 0) {
348
+ + return *total;
349
+ + }
350
+ + return 1;
351
+ +}
352
+ +
353
+ +static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
354
+ + int count, int *total)
355
+ +{
356
+ + *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
357
+ + if (*total < 0) {
358
+ + return *total;
359
+ + }
360
+ + return 1;
361
+ +}
362
+ +
363
+ +#define NOT_DONE 0x7fffffff
364
+ +static void aio_rw_done(void *opaque, int ret)
365
+ +{
366
+ + *(int *)opaque = ret;
367
+ +}
368
+ +
369
+ +static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
370
+ + int64_t offset, int *total)
371
+ +{
372
+ + int async_ret = NOT_DONE;
373
+ +
374
+ + bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
375
+ + aio_rw_done, &async_ret);
376
+ + while (async_ret == NOT_DONE) {
377
+ + main_loop_wait(false);
378
+ + }
379
+ +
380
+ + *total = qiov->size;
381
+ + return async_ret < 0 ? async_ret : 1;
382
+ +}
383
+ +
384
+ +static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
385
+ + int64_t offset, int *total)
386
+ +{
387
+ + int async_ret = NOT_DONE;
388
+ +
389
+ + bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
390
+ + aio_rw_done, &async_ret);
391
+ + while (async_ret == NOT_DONE) {
392
+ + main_loop_wait(false);
393
+ + }
394
+ +
395
+ + *total = qiov->size;
396
+ + return async_ret < 0 ? async_ret : 1;
397
+ +}
398
+ +
399
+ +struct multiwrite_async_ret {
400
+ + int num_done;
401
+ + int error;
402
+ +};
403
+ +
404
+ +static void multiwrite_cb(void *opaque, int ret)
405
+ +{
406
+ + struct multiwrite_async_ret *async_ret = opaque;
407
+ +
408
+ + async_ret->num_done++;
409
+ + if (ret < 0) {
410
+ + async_ret->error = ret;
411
+ + }
412
+ +}
413
+ +
414
+ +static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
415
+ + int num_reqs, int *total)
416
+ +{
417
+ + int i, ret;
418
+ + struct multiwrite_async_ret async_ret = {
419
+ + .num_done = 0,
420
+ + .error = 0,
421
+ + };
422
+ +
423
+ + *total = 0;
424
+ + for (i = 0; i < num_reqs; i++) {
425
+ + reqs[i].cb = multiwrite_cb;
426
+ + reqs[i].opaque = &async_ret;
427
+ + *total += reqs[i].qiov->size;
428
+ + }
429
+ +
430
+ + ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
431
+ + if (ret < 0) {
432
+ + return ret;
433
+ + }
434
+ +
435
+ + while (async_ret.num_done < num_reqs) {
436
+ + main_loop_wait(false);
437
+ + }
438
+ +
439
+ + return async_ret.error < 0 ? async_ret.error : 1;
440
+ +}
441
+ +
442
+ +static void read_help(void)
443
+ +{
444
+ + printf(
445
+ +"\n"
446
+ +" reads a range of bytes from the given offset\n"
447
+ +"\n"
448
+ +" Example:\n"
449
+ +" 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
450
+ +"\n"
451
+ +" Reads a segment of the currently open file, optionally dumping it to the\n"
452
+ +" standard output stream (with -v option) for subsequent inspection.\n"
453
+ +" -b, -- read from the VM state rather than the virtual disk\n"
454
+ +" -C, -- report statistics in a machine parsable format\n"
455
+ +" -l, -- length for pattern verification (only with -P)\n"
456
+ +" -p, -- use bdrv_pread to read the file\n"
457
+ +" -P, -- use a pattern to verify read data\n"
458
+ +" -q, -- quiet mode, do not show I/O statistics\n"
459
+ +" -s, -- start offset for pattern verification (only with -P)\n"
460
+ +" -v, -- dump buffer to standard output\n"
461
+ +"\n");
462
+ +}
463
+ +
464
+ +static int read_f(BlockDriverState *bs, int argc, char **argv);
465
+ +
466
+ +static const cmdinfo_t read_cmd = {
467
+ + .name = "read",
468
+ + .altname = "r",
469
+ + .cfunc = read_f,
470
+ + .argmin = 2,
471
+ + .argmax = -1,
472
+ + .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
473
+ + .oneline = "reads a number of bytes at a specified offset",
474
+ + .help = read_help,
475
+ +};
476
+ +
477
+ +static int read_f(BlockDriverState *bs, int argc, char **argv)
478
+ +{
479
+ + struct timeval t1, t2;
480
+ + int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
481
+ + int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
482
+ + int c, cnt;
483
+ + char *buf;
484
+ + int64_t offset;
485
+ + int count;
486
+ + /* Some compilers get confused and warn if this is not initialized. */
487
+ + int total = 0;
488
+ + int pattern = 0, pattern_offset = 0, pattern_count = 0;
489
+ +
490
+ + while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
491
+ + switch (c) {
492
+ + case 'b':
493
+ + bflag = 1;
494
+ + break;
495
+ + case 'C':
496
+ + Cflag = 1;
497
+ + break;
498
+ + case 'l':
499
+ + lflag = 1;
500
+ + pattern_count = cvtnum(optarg);
501
+ + if (pattern_count < 0) {
502
+ + printf("non-numeric length argument -- %s\n", optarg);
503
+ + return 0;
504
+ + }
505
+ + break;
506
+ + case 'p':
507
+ + pflag = 1;
508
+ + break;
509
+ + case 'P':
510
+ + Pflag = 1;
511
+ + pattern = parse_pattern(optarg);
512
+ + if (pattern < 0) {
513
+ + return 0;
514
+ + }
515
+ + break;
516
+ + case 'q':
517
+ + qflag = 1;
518
+ + break;
519
+ + case 's':
520
+ + sflag = 1;
521
+ + pattern_offset = cvtnum(optarg);
522
+ + if (pattern_offset < 0) {
523
+ + printf("non-numeric length argument -- %s\n", optarg);
524
+ + return 0;
525
+ + }
526
+ + break;
527
+ + case 'v':
528
+ + vflag = 1;
529
+ + break;
530
+ + default:
531
+ + return command_usage(&read_cmd);
532
+ + }
533
+ + }
534
+ +
535
+ + if (optind != argc - 2) {
536
+ + return command_usage(&read_cmd);
537
+ + }
538
+ +
539
+ + if (bflag && pflag) {
540
+ + printf("-b and -p cannot be specified at the same time\n");
541
+ + return 0;
542
+ + }
543
+ +
544
+ + offset = cvtnum(argv[optind]);
545
+ + if (offset < 0) {
546
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
547
+ + return 0;
548
+ + }
549
+ +
550
+ + optind++;
551
+ + count = cvtnum(argv[optind]);
552
+ + if (count < 0) {
553
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
554
+ + return 0;
555
+ + }
556
+ +
557
+ + if (!Pflag && (lflag || sflag)) {
558
+ + return command_usage(&read_cmd);
559
+ + }
560
+ +
561
+ + if (!lflag) {
562
+ + pattern_count = count - pattern_offset;
563
+ + }
564
+ +
565
+ + if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) {
566
+ + printf("pattern verification range exceeds end of read data\n");
567
+ + return 0;
568
+ + }
569
+ +
570
+ + if (!pflag) {
571
+ + if (offset & 0x1ff) {
572
+ + printf("offset %" PRId64 " is not sector aligned\n",
573
+ + offset);
574
+ + return 0;
575
+ + }
576
+ + if (count & 0x1ff) {
577
+ + printf("count %d is not sector aligned\n",
578
+ + count);
579
+ + return 0;
580
+ + }
581
+ + }
582
+ +
583
+ + buf = qemu_io_alloc(bs, count, 0xab);
584
+ +
585
+ + gettimeofday(&t1, NULL);
586
+ + if (pflag) {
587
+ + cnt = do_pread(bs, buf, offset, count, &total);
588
+ + } else if (bflag) {
589
+ + cnt = do_load_vmstate(bs, buf, offset, count, &total);
590
+ + } else {
591
+ + cnt = do_read(bs, buf, offset, count, &total);
592
+ + }
593
+ + gettimeofday(&t2, NULL);
594
+ +
595
+ + if (cnt < 0) {
596
+ + printf("read failed: %s\n", strerror(-cnt));
597
+ + goto out;
598
+ + }
599
+ +
600
+ + if (Pflag) {
601
+ + void *cmp_buf = g_malloc(pattern_count);
602
+ + memset(cmp_buf, pattern, pattern_count);
603
+ + if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
604
+ + printf("Pattern verification failed at offset %"
605
+ + PRId64 ", %d bytes\n",
606
+ + offset + pattern_offset, pattern_count);
607
+ + }
608
+ + g_free(cmp_buf);
609
+ + }
610
+ +
611
+ + if (qflag) {
612
+ + goto out;
613
+ + }
614
+ +
615
+ + if (vflag) {
616
+ + dump_buffer(buf, offset, count);
617
+ + }
618
+ +
619
+ + /* Finally, report back -- -C gives a parsable format */
620
+ + t2 = tsub(t2, t1);
621
+ + print_report("read", &t2, offset, count, total, cnt, Cflag);
622
+ +
623
+ +out:
624
+ + qemu_io_free(buf);
625
+ +
626
+ + return 0;
627
+ +}
628
+ +
629
+ +static void readv_help(void)
630
+ +{
631
+ + printf(
632
+ +"\n"
633
+ +" reads a range of bytes from the given offset into multiple buffers\n"
634
+ +"\n"
635
+ +" Example:\n"
636
+ +" 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
637
+ +"\n"
638
+ +" Reads a segment of the currently open file, optionally dumping it to the\n"
639
+ +" standard output stream (with -v option) for subsequent inspection.\n"
640
+ +" Uses multiple iovec buffers if more than one byte range is specified.\n"
641
+ +" -C, -- report statistics in a machine parsable format\n"
642
+ +" -P, -- use a pattern to verify read data\n"
643
+ +" -v, -- dump buffer to standard output\n"
644
+ +" -q, -- quiet mode, do not show I/O statistics\n"
645
+ +"\n");
646
+ +}
647
+ +
648
+ +static int readv_f(BlockDriverState *bs, int argc, char **argv);
649
+ +
650
+ +static const cmdinfo_t readv_cmd = {
651
+ + .name = "readv",
652
+ + .cfunc = readv_f,
653
+ + .argmin = 2,
654
+ + .argmax = -1,
655
+ + .args = "[-Cqv] [-P pattern ] off len [len..]",
656
+ + .oneline = "reads a number of bytes at a specified offset",
657
+ + .help = readv_help,
658
+ +};
659
+ +
660
+ +static int readv_f(BlockDriverState *bs, int argc, char **argv)
661
+ +{
662
+ + struct timeval t1, t2;
663
+ + int Cflag = 0, qflag = 0, vflag = 0;
664
+ + int c, cnt;
665
+ + char *buf;
666
+ + int64_t offset;
667
+ + /* Some compilers get confused and warn if this is not initialized. */
668
+ + int total = 0;
669
+ + int nr_iov;
670
+ + QEMUIOVector qiov;
671
+ + int pattern = 0;
672
+ + int Pflag = 0;
673
+ +
674
+ + while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
675
+ + switch (c) {
676
+ + case 'C':
677
+ + Cflag = 1;
678
+ + break;
679
+ + case 'P':
680
+ + Pflag = 1;
681
+ + pattern = parse_pattern(optarg);
682
+ + if (pattern < 0) {
683
+ + return 0;
684
+ + }
685
+ + break;
686
+ + case 'q':
687
+ + qflag = 1;
688
+ + break;
689
+ + case 'v':
690
+ + vflag = 1;
691
+ + break;
692
+ + default:
693
+ + return command_usage(&readv_cmd);
694
+ + }
695
+ + }
696
+ +
697
+ + if (optind > argc - 2) {
698
+ + return command_usage(&readv_cmd);
699
+ + }
700
+ +
701
+ +
702
+ + offset = cvtnum(argv[optind]);
703
+ + if (offset < 0) {
704
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
705
+ + return 0;
706
+ + }
707
+ + optind++;
708
+ +
709
+ + if (offset & 0x1ff) {
710
+ + printf("offset %" PRId64 " is not sector aligned\n",
711
+ + offset);
712
+ + return 0;
713
+ + }
714
+ +
715
+ + nr_iov = argc - optind;
716
+ + buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
717
+ + if (buf == NULL) {
718
+ + return 0;
719
+ + }
720
+ +
721
+ + gettimeofday(&t1, NULL);
722
+ + cnt = do_aio_readv(bs, &qiov, offset, &total);
723
+ + gettimeofday(&t2, NULL);
724
+ +
725
+ + if (cnt < 0) {
726
+ + printf("readv failed: %s\n", strerror(-cnt));
727
+ + goto out;
728
+ + }
729
+ +
730
+ + if (Pflag) {
731
+ + void *cmp_buf = g_malloc(qiov.size);
732
+ + memset(cmp_buf, pattern, qiov.size);
733
+ + if (memcmp(buf, cmp_buf, qiov.size)) {
734
+ + printf("Pattern verification failed at offset %"
735
+ + PRId64 ", %zd bytes\n", offset, qiov.size);
736
+ + }
737
+ + g_free(cmp_buf);
738
+ + }
739
+ +
740
+ + if (qflag) {
741
+ + goto out;
742
+ + }
743
+ +
744
+ + if (vflag) {
745
+ + dump_buffer(buf, offset, qiov.size);
746
+ + }
747
+ +
748
+ + /* Finally, report back -- -C gives a parsable format */
749
+ + t2 = tsub(t2, t1);
750
+ + print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
751
+ +
752
+ +out:
753
+ + qemu_iovec_destroy(&qiov);
754
+ + qemu_io_free(buf);
755
+ + return 0;
756
+ +}
757
+ +
758
+ +static void write_help(void)
759
+ +{
760
+ + printf(
761
+ +"\n"
762
+ +" writes a range of bytes from the given offset\n"
763
+ +"\n"
764
+ +" Example:\n"
765
+ +" 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
766
+ +"\n"
767
+ +" Writes into a segment of the currently open file, using a buffer\n"
768
+ +" filled with a set pattern (0xcdcdcdcd).\n"
769
+ +" -b, -- write to the VM state rather than the virtual disk\n"
770
+ +" -c, -- write compressed data with bdrv_write_compressed\n"
771
+ +" -p, -- use bdrv_pwrite to write the file\n"
772
+ +" -P, -- use different pattern to fill file\n"
773
+ +" -C, -- report statistics in a machine parsable format\n"
774
+ +" -q, -- quiet mode, do not show I/O statistics\n"
775
+ +" -z, -- write zeroes using bdrv_co_write_zeroes\n"
776
+ +"\n");
777
+ +}
778
+ +
779
+ +static int write_f(BlockDriverState *bs, int argc, char **argv);
780
+ +
781
+ +static const cmdinfo_t write_cmd = {
782
+ + .name = "write",
783
+ + .altname = "w",
784
+ + .cfunc = write_f,
785
+ + .argmin = 2,
786
+ + .argmax = -1,
787
+ + .args = "[-bcCpqz] [-P pattern ] off len",
788
+ + .oneline = "writes a number of bytes at a specified offset",
789
+ + .help = write_help,
790
+ +};
791
+ +
792
+ +static int write_f(BlockDriverState *bs, int argc, char **argv)
793
+ +{
794
+ + struct timeval t1, t2;
795
+ + int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
796
+ + int cflag = 0;
797
+ + int c, cnt;
798
+ + char *buf = NULL;
799
+ + int64_t offset;
800
+ + int count;
801
+ + /* Some compilers get confused and warn if this is not initialized. */
802
+ + int total = 0;
803
+ + int pattern = 0xcd;
804
+ +
805
+ + while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
806
+ + switch (c) {
807
+ + case 'b':
808
+ + bflag = 1;
809
+ + break;
810
+ + case 'c':
811
+ + cflag = 1;
812
+ + break;
813
+ + case 'C':
814
+ + Cflag = 1;
815
+ + break;
816
+ + case 'p':
817
+ + pflag = 1;
818
+ + break;
819
+ + case 'P':
820
+ + Pflag = 1;
821
+ + pattern = parse_pattern(optarg);
822
+ + if (pattern < 0) {
823
+ + return 0;
824
+ + }
825
+ + break;
826
+ + case 'q':
827
+ + qflag = 1;
828
+ + break;
829
+ + case 'z':
830
+ + zflag = 1;
831
+ + break;
832
+ + default:
833
+ + return command_usage(&write_cmd);
834
+ + }
835
+ + }
836
+ +
837
+ + if (optind != argc - 2) {
838
+ + return command_usage(&write_cmd);
839
+ + }
840
+ +
841
+ + if (bflag + pflag + zflag > 1) {
842
+ + printf("-b, -p, or -z cannot be specified at the same time\n");
843
+ + return 0;
844
+ + }
845
+ +
846
+ + if (zflag && Pflag) {
847
+ + printf("-z and -P cannot be specified at the same time\n");
848
+ + return 0;
849
+ + }
850
+ +
851
+ + offset = cvtnum(argv[optind]);
852
+ + if (offset < 0) {
853
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
854
+ + return 0;
855
+ + }
856
+ +
857
+ + optind++;
858
+ + count = cvtnum(argv[optind]);
859
+ + if (count < 0) {
860
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
861
+ + return 0;
862
+ + }
863
+ +
864
+ + if (!pflag) {
865
+ + if (offset & 0x1ff) {
866
+ + printf("offset %" PRId64 " is not sector aligned\n",
867
+ + offset);
868
+ + return 0;
869
+ + }
870
+ +
871
+ + if (count & 0x1ff) {
872
+ + printf("count %d is not sector aligned\n",
873
+ + count);
874
+ + return 0;
875
+ + }
876
+ + }
877
+ +
878
+ + if (!zflag) {
879
+ + buf = qemu_io_alloc(bs, count, pattern);
880
+ + }
881
+ +
882
+ + gettimeofday(&t1, NULL);
883
+ + if (pflag) {
884
+ + cnt = do_pwrite(bs, buf, offset, count, &total);
885
+ + } else if (bflag) {
886
+ + cnt = do_save_vmstate(bs, buf, offset, count, &total);
887
+ + } else if (zflag) {
888
+ + cnt = do_co_write_zeroes(bs, offset, count, &total);
889
+ + } else if (cflag) {
890
+ + cnt = do_write_compressed(bs, buf, offset, count, &total);
891
+ + } else {
892
+ + cnt = do_write(bs, buf, offset, count, &total);
893
+ + }
894
+ + gettimeofday(&t2, NULL);
895
+ +
896
+ + if (cnt < 0) {
897
+ + printf("write failed: %s\n", strerror(-cnt));
898
+ + goto out;
899
+ + }
900
+ +
901
+ + if (qflag) {
902
+ + goto out;
903
+ + }
904
+ +
905
+ + /* Finally, report back -- -C gives a parsable format */
906
+ + t2 = tsub(t2, t1);
907
+ + print_report("wrote", &t2, offset, count, total, cnt, Cflag);
908
+ +
909
+ +out:
910
+ + if (!zflag) {
911
+ + qemu_io_free(buf);
912
+ + }
913
+ +
914
+ + return 0;
915
+ +}
916
+ +
917
+ +static void
918
+ +writev_help(void)
919
+ +{
920
+ + printf(
921
+ +"\n"
922
+ +" writes a range of bytes from the given offset source from multiple buffers\n"
923
+ +"\n"
924
+ +" Example:\n"
925
+ +" 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
926
+ +"\n"
927
+ +" Writes into a segment of the currently open file, using a buffer\n"
928
+ +" filled with a set pattern (0xcdcdcdcd).\n"
929
+ +" -P, -- use different pattern to fill file\n"
930
+ +" -C, -- report statistics in a machine parsable format\n"
931
+ +" -q, -- quiet mode, do not show I/O statistics\n"
932
+ +"\n");
933
+ +}
934
+ +
935
+ +static int writev_f(BlockDriverState *bs, int argc, char **argv);
936
+ +
937
+ +static const cmdinfo_t writev_cmd = {
938
+ + .name = "writev",
939
+ + .cfunc = writev_f,
940
+ + .argmin = 2,
941
+ + .argmax = -1,
942
+ + .args = "[-Cq] [-P pattern ] off len [len..]",
943
+ + .oneline = "writes a number of bytes at a specified offset",
944
+ + .help = writev_help,
945
+ +};
946
+ +
947
+ +static int writev_f(BlockDriverState *bs, int argc, char **argv)
948
+ +{
949
+ + struct timeval t1, t2;
950
+ + int Cflag = 0, qflag = 0;
951
+ + int c, cnt;
952
+ + char *buf;
953
+ + int64_t offset;
954
+ + /* Some compilers get confused and warn if this is not initialized. */
955
+ + int total = 0;
956
+ + int nr_iov;
957
+ + int pattern = 0xcd;
958
+ + QEMUIOVector qiov;
959
+ +
960
+ + while ((c = getopt(argc, argv, "CqP:")) != EOF) {
961
+ + switch (c) {
962
+ + case 'C':
963
+ + Cflag = 1;
964
+ + break;
965
+ + case 'q':
966
+ + qflag = 1;
967
+ + break;
968
+ + case 'P':
969
+ + pattern = parse_pattern(optarg);
970
+ + if (pattern < 0) {
971
+ + return 0;
972
+ + }
973
+ + break;
974
+ + default:
975
+ + return command_usage(&writev_cmd);
976
+ + }
977
+ + }
978
+ +
979
+ + if (optind > argc - 2) {
980
+ + return command_usage(&writev_cmd);
981
+ + }
982
+ +
983
+ + offset = cvtnum(argv[optind]);
984
+ + if (offset < 0) {
985
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
986
+ + return 0;
987
+ + }
988
+ + optind++;
989
+ +
990
+ + if (offset & 0x1ff) {
991
+ + printf("offset %" PRId64 " is not sector aligned\n",
992
+ + offset);
993
+ + return 0;
994
+ + }
995
+ +
996
+ + nr_iov = argc - optind;
997
+ + buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
998
+ + if (buf == NULL) {
999
+ + return 0;
1000
+ + }
1001
+ +
1002
+ + gettimeofday(&t1, NULL);
1003
+ + cnt = do_aio_writev(bs, &qiov, offset, &total);
1004
+ + gettimeofday(&t2, NULL);
1005
+ +
1006
+ + if (cnt < 0) {
1007
+ + printf("writev failed: %s\n", strerror(-cnt));
1008
+ + goto out;
1009
+ + }
1010
+ +
1011
+ + if (qflag) {
1012
+ + goto out;
1013
+ + }
1014
+ +
1015
+ + /* Finally, report back -- -C gives a parsable format */
1016
+ + t2 = tsub(t2, t1);
1017
+ + print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
1018
+ +out:
1019
+ + qemu_iovec_destroy(&qiov);
1020
+ + qemu_io_free(buf);
1021
+ + return 0;
1022
+ +}
1023
+ +
1024
+ +static void multiwrite_help(void)
1025
+ +{
1026
+ + printf(
1027
+ +"\n"
1028
+ +" writes a range of bytes from the given offset source from multiple buffers,\n"
1029
+ +" in a batch of requests that may be merged by qemu\n"
1030
+ +"\n"
1031
+ +" Example:\n"
1032
+ +" 'multiwrite 512 1k 1k ; 4k 1k'\n"
1033
+ +" writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
1034
+ +"\n"
1035
+ +" Writes into a segment of the currently open file, using a buffer\n"
1036
+ +" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
1037
+ +" by one for each request contained in the multiwrite command.\n"
1038
+ +" -P, -- use different pattern to fill file\n"
1039
+ +" -C, -- report statistics in a machine parsable format\n"
1040
+ +" -q, -- quiet mode, do not show I/O statistics\n"
1041
+ +"\n");
1042
+ +}
1043
+ +
1044
+ +static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
1045
+ +
1046
+ +static const cmdinfo_t multiwrite_cmd = {
1047
+ + .name = "multiwrite",
1048
+ + .cfunc = multiwrite_f,
1049
+ + .argmin = 2,
1050
+ + .argmax = -1,
1051
+ + .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
1052
+ + .oneline = "issues multiple write requests at once",
1053
+ + .help = multiwrite_help,
1054
+ +};
1055
+ +
1056
+ +static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
1057
+ +{
1058
+ + struct timeval t1, t2;
1059
+ + int Cflag = 0, qflag = 0;
1060
+ + int c, cnt;
1061
+ + char **buf;
1062
+ + int64_t offset, first_offset = 0;
1063
+ + /* Some compilers get confused and warn if this is not initialized. */
1064
+ + int total = 0;
1065
+ + int nr_iov;
1066
+ + int nr_reqs;
1067
+ + int pattern = 0xcd;
1068
+ + QEMUIOVector *qiovs;
1069
+ + int i;
1070
+ + BlockRequest *reqs;
1071
+ +
1072
+ + while ((c = getopt(argc, argv, "CqP:")) != EOF) {
1073
+ + switch (c) {
1074
+ + case 'C':
1075
+ + Cflag = 1;
1076
+ + break;
1077
+ + case 'q':
1078
+ + qflag = 1;
1079
+ + break;
1080
+ + case 'P':
1081
+ + pattern = parse_pattern(optarg);
1082
+ + if (pattern < 0) {
1083
+ + return 0;
1084
+ + }
1085
+ + break;
1086
+ + default:
1087
+ + return command_usage(&writev_cmd);
1088
+ + }
1089
+ + }
1090
+ +
1091
+ + if (optind > argc - 2) {
1092
+ + return command_usage(&writev_cmd);
1093
+ + }
1094
+ +
1095
+ + nr_reqs = 1;
1096
+ + for (i = optind; i < argc; i++) {
1097
+ + if (!strcmp(argv[i], ";")) {
1098
+ + nr_reqs++;
1099
+ + }
1100
+ + }
1101
+ +
1102
+ + reqs = g_malloc0(nr_reqs * sizeof(*reqs));
1103
+ + buf = g_malloc0(nr_reqs * sizeof(*buf));
1104
+ + qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
1105
+ +
1106
+ + for (i = 0; i < nr_reqs && optind < argc; i++) {
1107
+ + int j;
1108
+ +
1109
+ + /* Read the offset of the request */
1110
+ + offset = cvtnum(argv[optind]);
1111
+ + if (offset < 0) {
1112
+ + printf("non-numeric offset argument -- %s\n", argv[optind]);
1113
+ + goto out;
1114
+ + }
1115
+ + optind++;
1116
+ +
1117
+ + if (offset & 0x1ff) {
1118
+ + printf("offset %lld is not sector aligned\n",
1119
+ + (long long)offset);
1120
+ + goto out;
1121
+ + }
1122
+ +
1123
+ + if (i == 0) {
1124
+ + first_offset = offset;
1125
+ + }
1126
+ +
1127
+ + /* Read lengths for qiov entries */
1128
+ + for (j = optind; j < argc; j++) {
1129
+ + if (!strcmp(argv[j], ";")) {
1130
+ + break;
1131
+ + }
1132
+ + }
1133
+ +
1134
+ + nr_iov = j - optind;
1135
+ +
1136
+ + /* Build request */
1137
+ + buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
1138
+ + if (buf[i] == NULL) {
1139
+ + goto out;
1140
+ + }
1141
+ +
1142
+ + reqs[i].qiov = &qiovs[i];
1143
+ + reqs[i].sector = offset >> 9;
1144
+ + reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
1145
+ +
1146
+ + optind = j + 1;
1147
+ +
1148
+ + pattern++;
1149
+ + }
1150
+ +
1151
+ + /* If there were empty requests at the end, ignore them */
1152
+ + nr_reqs = i;
1153
+ +
1154
+ + gettimeofday(&t1, NULL);
1155
+ + cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
1156
+ + gettimeofday(&t2, NULL);
1157
+ +
1158
+ + if (cnt < 0) {
1159
+ + printf("aio_multiwrite failed: %s\n", strerror(-cnt));
1160
+ + goto out;
1161
+ + }
1162
+ +
1163
+ + if (qflag) {
1164
+ + goto out;
1165
+ + }
1166
+ +
1167
+ + /* Finally, report back -- -C gives a parsable format */
1168
+ + t2 = tsub(t2, t1);
1169
+ + print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
1170
+ +out:
1171
+ + for (i = 0; i < nr_reqs; i++) {
1172
+ + qemu_io_free(buf[i]);
1173
+ + if (reqs[i].qiov != NULL) {
1174
+ + qemu_iovec_destroy(&qiovs[i]);
1175
+ + }
1176
+ + }
1177
+ + g_free(buf);
1178
+ + g_free(reqs);
1179
+ + g_free(qiovs);
1180
+ + return 0;
1181
+ +}
1182
+ +
1183
+ +struct aio_ctx {
1184
+ + QEMUIOVector qiov;
1185
+ + int64_t offset;
1186
+ + char *buf;
1187
+ + int qflag;
1188
+ + int vflag;
1189
+ + int Cflag;
1190
+ + int Pflag;
1191
+ + int pattern;
1192
+ + struct timeval t1;
1193
+ +};
1194
+ +
1195
+ +static void aio_write_done(void *opaque, int ret)
1196
+ +{
1197
+ + struct aio_ctx *ctx = opaque;
1198
+ + struct timeval t2;
1199
+ +
1200
+ + gettimeofday(&t2, NULL);
1201
+ +
1202
+ +
1203
+ + if (ret < 0) {
1204
+ + printf("aio_write failed: %s\n", strerror(-ret));
1205
+ + goto out;
1206
+ + }
1207
+ +
1208
+ + if (ctx->qflag) {
1209
+ + goto out;
1210
+ + }
1211
+ +
1212
+ + /* Finally, report back -- -C gives a parsable format */
1213
+ + t2 = tsub(t2, ctx->t1);
1214
+ + print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
1215
+ + ctx->qiov.size, 1, ctx->Cflag);
1216
+ +out:
1217
+ + qemu_io_free(ctx->buf);
1218
+ + qemu_iovec_destroy(&ctx->qiov);
1219
+ + g_free(ctx);
1220
+ +}
1221
+ +
1222
+ +static void aio_read_done(void *opaque, int ret)
1223
+ +{
1224
+ + struct aio_ctx *ctx = opaque;
1225
+ + struct timeval t2;
1226
+ +
1227
+ + gettimeofday(&t2, NULL);
1228
+ +
1229
+ + if (ret < 0) {
1230
+ + printf("readv failed: %s\n", strerror(-ret));
1231
+ + goto out;
1232
+ + }
1233
+ +
1234
+ + if (ctx->Pflag) {
1235
+ + void *cmp_buf = g_malloc(ctx->qiov.size);
1236
+ +
1237
+ + memset(cmp_buf, ctx->pattern, ctx->qiov.size);
1238
+ + if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
1239
+ + printf("Pattern verification failed at offset %"
1240
+ + PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
1241
+ + }
1242
+ + g_free(cmp_buf);
1243
+ + }
1244
+ +
1245
+ + if (ctx->qflag) {
1246
+ + goto out;
1247
+ + }
1248
+ +
1249
+ + if (ctx->vflag) {
1250
+ + dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
1251
+ + }
1252
+ +
1253
+ + /* Finally, report back -- -C gives a parsable format */
1254
+ + t2 = tsub(t2, ctx->t1);
1255
+ + print_report("read", &t2, ctx->offset, ctx->qiov.size,
1256
+ + ctx->qiov.size, 1, ctx->Cflag);
1257
+ +out:
1258
+ + qemu_io_free(ctx->buf);
1259
+ + qemu_iovec_destroy(&ctx->qiov);
1260
+ + g_free(ctx);
1261
+ +}
1262
+ +
1263
+ +static void aio_read_help(void)
1264
+ +{
1265
+ + printf(
1266
+ +"\n"
1267
+ +" asynchronously reads a range of bytes from the given offset\n"
1268
+ +"\n"
1269
+ +" Example:\n"
1270
+ +" 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
1271
+ +"\n"
1272
+ +" Reads a segment of the currently open file, optionally dumping it to the\n"
1273
+ +" standard output stream (with -v option) for subsequent inspection.\n"
1274
+ +" The read is performed asynchronously and the aio_flush command must be\n"
1275
+ +" used to ensure all outstanding aio requests have been completed.\n"
1276
+ +" -C, -- report statistics in a machine parsable format\n"
1277
+ +" -P, -- use a pattern to verify read data\n"
1278
+ +" -v, -- dump buffer to standard output\n"
1279
+ +" -q, -- quiet mode, do not show I/O statistics\n"
1280
+ +"\n");
1281
+ +}
1282
+ +
1283
+ +static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
1284
+ +
1285
+ +static const cmdinfo_t aio_read_cmd = {
1286
+ + .name = "aio_read",
1287
+ + .cfunc = aio_read_f,
1288
+ + .argmin = 2,
1289
+ + .argmax = -1,
1290
+ + .args = "[-Cqv] [-P pattern ] off len [len..]",
1291
+ + .oneline = "asynchronously reads a number of bytes",
1292
+ + .help = aio_read_help,
1293
+ +};
1294
+ +
1295
+ +static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
1296
+ +{
1297
+ + int nr_iov, c;
1298
+ + struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1299
+ +
1300
+ + while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
1301
+ + switch (c) {
1302
+ + case 'C':
1303
+ + ctx->Cflag = 1;
1304
+ + break;
1305
+ + case 'P':
1306
+ + ctx->Pflag = 1;
1307
+ + ctx->pattern = parse_pattern(optarg);
1308
+ + if (ctx->pattern < 0) {
1309
+ + g_free(ctx);
1310
+ + return 0;
1311
+ + }
1312
+ + break;
1313
+ + case 'q':
1314
+ + ctx->qflag = 1;
1315
+ + break;
1316
+ + case 'v':
1317
+ + ctx->vflag = 1;
1318
+ + break;
1319
+ + default:
1320
+ + g_free(ctx);
1321
+ + return command_usage(&aio_read_cmd);
1322
+ + }
1323
+ + }
1324
+ +
1325
+ + if (optind > argc - 2) {
1326
+ + g_free(ctx);
1327
+ + return command_usage(&aio_read_cmd);
1328
+ + }
1329
+ +
1330
+ + ctx->offset = cvtnum(argv[optind]);
1331
+ + if (ctx->offset < 0) {
1332
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
1333
+ + g_free(ctx);
1334
+ + return 0;
1335
+ + }
1336
+ + optind++;
1337
+ +
1338
+ + if (ctx->offset & 0x1ff) {
1339
+ + printf("offset %" PRId64 " is not sector aligned\n",
1340
+ + ctx->offset);
1341
+ + g_free(ctx);
1342
+ + return 0;
1343
+ + }
1344
+ +
1345
+ + nr_iov = argc - optind;
1346
+ + ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
1347
+ + if (ctx->buf == NULL) {
1348
+ + g_free(ctx);
1349
+ + return 0;
1350
+ + }
1351
+ +
1352
+ + gettimeofday(&ctx->t1, NULL);
1353
+ + bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
1354
+ + ctx->qiov.size >> 9, aio_read_done, ctx);
1355
+ + return 0;
1356
+ +}
1357
+ +
1358
+ +static void aio_write_help(void)
1359
+ +{
1360
+ + printf(
1361
+ +"\n"
1362
+ +" asynchronously writes a range of bytes from the given offset source\n"
1363
+ +" from multiple buffers\n"
1364
+ +"\n"
1365
+ +" Example:\n"
1366
+ +" 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1367
+ +"\n"
1368
+ +" Writes into a segment of the currently open file, using a buffer\n"
1369
+ +" filled with a set pattern (0xcdcdcdcd).\n"
1370
+ +" The write is performed asynchronously and the aio_flush command must be\n"
1371
+ +" used to ensure all outstanding aio requests have been completed.\n"
1372
+ +" -P, -- use different pattern to fill file\n"
1373
+ +" -C, -- report statistics in a machine parsable format\n"
1374
+ +" -q, -- quiet mode, do not show I/O statistics\n"
1375
+ +"\n");
1376
+ +}
1377
+ +
1378
+ +static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
1379
+ +
1380
+ +static const cmdinfo_t aio_write_cmd = {
1381
+ + .name = "aio_write",
1382
+ + .cfunc = aio_write_f,
1383
+ + .argmin = 2,
1384
+ + .argmax = -1,
1385
+ + .args = "[-Cq] [-P pattern ] off len [len..]",
1386
+ + .oneline = "asynchronously writes a number of bytes",
1387
+ + .help = aio_write_help,
1388
+ +};
1389
+ +
1390
+ +static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
1391
+ +{
1392
+ + int nr_iov, c;
1393
+ + int pattern = 0xcd;
1394
+ + struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1395
+ +
1396
+ + while ((c = getopt(argc, argv, "CqP:")) != EOF) {
1397
+ + switch (c) {
1398
+ + case 'C':
1399
+ + ctx->Cflag = 1;
1400
+ + break;
1401
+ + case 'q':
1402
+ + ctx->qflag = 1;
1403
+ + break;
1404
+ + case 'P':
1405
+ + pattern = parse_pattern(optarg);
1406
+ + if (pattern < 0) {
1407
+ + g_free(ctx);
1408
+ + return 0;
1409
+ + }
1410
+ + break;
1411
+ + default:
1412
+ + g_free(ctx);
1413
+ + return command_usage(&aio_write_cmd);
1414
+ + }
1415
+ + }
1416
+ +
1417
+ + if (optind > argc - 2) {
1418
+ + g_free(ctx);
1419
+ + return command_usage(&aio_write_cmd);
1420
+ + }
1421
+ +
1422
+ + ctx->offset = cvtnum(argv[optind]);
1423
+ + if (ctx->offset < 0) {
1424
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
1425
+ + g_free(ctx);
1426
+ + return 0;
1427
+ + }
1428
+ + optind++;
1429
+ +
1430
+ + if (ctx->offset & 0x1ff) {
1431
+ + printf("offset %" PRId64 " is not sector aligned\n",
1432
+ + ctx->offset);
1433
+ + g_free(ctx);
1434
+ + return 0;
1435
+ + }
1436
+ +
1437
+ + nr_iov = argc - optind;
1438
+ + ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
1439
+ + if (ctx->buf == NULL) {
1440
+ + g_free(ctx);
1441
+ + return 0;
1442
+ + }
1443
+ +
1444
+ + gettimeofday(&ctx->t1, NULL);
1445
+ + bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
1446
+ + ctx->qiov.size >> 9, aio_write_done, ctx);
1447
+ + return 0;
1448
+ +}
1449
+ +
1450
+ +static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
1451
+ +{
1452
+ + bdrv_drain_all();
1453
+ + return 0;
1454
+ +}
1455
+ +
1456
+ +static const cmdinfo_t aio_flush_cmd = {
1457
+ + .name = "aio_flush",
1458
+ + .cfunc = aio_flush_f,
1459
+ + .oneline = "completes all outstanding aio requests"
1460
+ +};
1461
+ +
1462
+ +static int flush_f(BlockDriverState *bs, int argc, char **argv)
1463
+ +{
1464
+ + bdrv_flush(bs);
1465
+ + return 0;
1466
+ +}
1467
+ +
1468
+ +static const cmdinfo_t flush_cmd = {
1469
+ + .name = "flush",
1470
+ + .altname = "f",
1471
+ + .cfunc = flush_f,
1472
+ + .oneline = "flush all in-core file state to disk",
1473
+ +};
1474
+ +
1475
+ +static int truncate_f(BlockDriverState *bs, int argc, char **argv)
1476
+ +{
1477
+ + int64_t offset;
1478
+ + int ret;
1479
+ +
1480
+ + offset = cvtnum(argv[1]);
1481
+ + if (offset < 0) {
1482
+ + printf("non-numeric truncate argument -- %s\n", argv[1]);
1483
+ + return 0;
1484
+ + }
1485
+ +
1486
+ + ret = bdrv_truncate(bs, offset);
1487
+ + if (ret < 0) {
1488
+ + printf("truncate: %s\n", strerror(-ret));
1489
+ + return 0;
1490
+ + }
1491
+ +
1492
+ + return 0;
1493
+ +}
1494
+ +
1495
+ +static const cmdinfo_t truncate_cmd = {
1496
+ + .name = "truncate",
1497
+ + .altname = "t",
1498
+ + .cfunc = truncate_f,
1499
+ + .argmin = 1,
1500
+ + .argmax = 1,
1501
+ + .args = "off",
1502
+ + .oneline = "truncates the current file at the given offset",
1503
+ +};
1504
+ +
1505
+ +static int length_f(BlockDriverState *bs, int argc, char **argv)
1506
+ +{
1507
+ + int64_t size;
1508
+ + char s1[64];
1509
+ +
1510
+ + size = bdrv_getlength(bs);
1511
+ + if (size < 0) {
1512
+ + printf("getlength: %s\n", strerror(-size));
1513
+ + return 0;
1514
+ + }
1515
+ +
1516
+ + cvtstr(size, s1, sizeof(s1));
1517
+ + printf("%s\n", s1);
1518
+ + return 0;
1519
+ +}
1520
+ +
1521
+ +
1522
+ +static const cmdinfo_t length_cmd = {
1523
+ + .name = "length",
1524
+ + .altname = "l",
1525
+ + .cfunc = length_f,
1526
+ + .oneline = "gets the length of the current file",
1527
+ +};
1528
+ +
1529
+ +
1530
+ +static int info_f(BlockDriverState *bs, int argc, char **argv)
1531
+ +{
1532
+ + BlockDriverInfo bdi;
1533
+ + ImageInfoSpecific *spec_info;
1534
+ + char s1[64], s2[64];
1535
+ + int ret;
1536
+ +
1537
+ + if (bs->drv && bs->drv->format_name) {
1538
+ + printf("format name: %s\n", bs->drv->format_name);
1539
+ + }
1540
+ + if (bs->drv && bs->drv->protocol_name) {
1541
+ + printf("format name: %s\n", bs->drv->protocol_name);
1542
+ + }
1543
+ +
1544
+ + ret = bdrv_get_info(bs, &bdi);
1545
+ + if (ret) {
1546
+ + return 0;
1547
+ + }
1548
+ +
1549
+ + cvtstr(bdi.cluster_size, s1, sizeof(s1));
1550
+ + cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
1551
+ +
1552
+ + printf("cluster size: %s\n", s1);
1553
+ + printf("vm state offset: %s\n", s2);
1554
+ +
1555
+ + spec_info = bdrv_get_specific_info(bs);
1556
+ + if (spec_info) {
1557
+ + printf("Format specific information:\n");
1558
+ + bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
1559
+ + qapi_free_ImageInfoSpecific(spec_info);
1560
+ + }
1561
+ +
1562
+ + return 0;
1563
+ +}
1564
+ +
1565
+ +
1566
+ +
1567
+ +static const cmdinfo_t info_cmd = {
1568
+ + .name = "info",
1569
+ + .altname = "i",
1570
+ + .cfunc = info_f,
1571
+ + .oneline = "prints information about the current file",
1572
+ +};
1573
+ +
1574
+ +static void discard_help(void)
1575
+ +{
1576
+ + printf(
1577
+ +"\n"
1578
+ +" discards a range of bytes from the given offset\n"
1579
+ +"\n"
1580
+ +" Example:\n"
1581
+ +" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
1582
+ +"\n"
1583
+ +" Discards a segment of the currently open file.\n"
1584
+ +" -C, -- report statistics in a machine parsable format\n"
1585
+ +" -q, -- quiet mode, do not show I/O statistics\n"
1586
+ +"\n");
1587
+ +}
1588
+ +
1589
+ +static int discard_f(BlockDriverState *bs, int argc, char **argv);
1590
+ +
1591
+ +static const cmdinfo_t discard_cmd = {
1592
+ + .name = "discard",
1593
+ + .altname = "d",
1594
+ + .cfunc = discard_f,
1595
+ + .argmin = 2,
1596
+ + .argmax = -1,
1597
+ + .args = "[-Cq] off len",
1598
+ + .oneline = "discards a number of bytes at a specified offset",
1599
+ + .help = discard_help,
1600
+ +};
1601
+ +
1602
+ +static int discard_f(BlockDriverState *bs, int argc, char **argv)
1603
+ +{
1604
+ + struct timeval t1, t2;
1605
+ + int Cflag = 0, qflag = 0;
1606
+ + int c, ret;
1607
+ + int64_t offset;
1608
+ + int count;
1609
+ +
1610
+ + while ((c = getopt(argc, argv, "Cq")) != EOF) {
1611
+ + switch (c) {
1612
+ + case 'C':
1613
+ + Cflag = 1;
1614
+ + break;
1615
+ + case 'q':
1616
+ + qflag = 1;
1617
+ + break;
1618
+ + default:
1619
+ + return command_usage(&discard_cmd);
1620
+ + }
1621
+ + }
1622
+ +
1623
+ + if (optind != argc - 2) {
1624
+ + return command_usage(&discard_cmd);
1625
+ + }
1626
+ +
1627
+ + offset = cvtnum(argv[optind]);
1628
+ + if (offset < 0) {
1629
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
1630
+ + return 0;
1631
+ + }
1632
+ +
1633
+ + optind++;
1634
+ + count = cvtnum(argv[optind]);
1635
+ + if (count < 0) {
1636
+ + printf("non-numeric length argument -- %s\n", argv[optind]);
1637
+ + return 0;
1638
+ + }
1639
+ +
1640
+ + gettimeofday(&t1, NULL);
1641
+ + ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
1642
+ + count >> BDRV_SECTOR_BITS);
1643
+ + gettimeofday(&t2, NULL);
1644
+ +
1645
+ + if (ret < 0) {
1646
+ + printf("discard failed: %s\n", strerror(-ret));
1647
+ + goto out;
1648
+ + }
1649
+ +
1650
+ + /* Finally, report back -- -C gives a parsable format */
1651
+ + if (!qflag) {
1652
+ + t2 = tsub(t2, t1);
1653
+ + print_report("discard", &t2, offset, count, count, 1, Cflag);
1654
+ + }
1655
+ +
1656
+ +out:
1657
+ + return 0;
1658
+ +}
1659
+ +
1660
+ +static int alloc_f(BlockDriverState *bs, int argc, char **argv)
1661
+ +{
1662
+ + int64_t offset, sector_num;
1663
+ + int nb_sectors, remaining;
1664
+ + char s1[64];
1665
+ + int num, sum_alloc;
1666
+ + int ret;
1667
+ +
1668
+ + offset = cvtnum(argv[1]);
1669
+ + if (offset < 0) {
1670
+ + printf("non-numeric offset argument -- %s\n", argv[1]);
1671
+ + return 0;
1672
+ + } else if (offset & 0x1ff) {
1673
+ + printf("offset %" PRId64 " is not sector aligned\n",
1674
+ + offset);
1675
+ + return 0;
1676
+ + }
1677
+ +
1678
+ + if (argc == 3) {
1679
+ + nb_sectors = cvtnum(argv[2]);
1680
+ + if (nb_sectors < 0) {
1681
+ + printf("non-numeric length argument -- %s\n", argv[2]);
1682
+ + return 0;
1683
+ + }
1684
+ + } else {
1685
+ + nb_sectors = 1;
1686
+ + }
1687
+ +
1688
+ + remaining = nb_sectors;
1689
+ + sum_alloc = 0;
1690
+ + sector_num = offset >> 9;
1691
+ + while (remaining) {
1692
+ + ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
1693
+ + if (ret < 0) {
1694
+ + printf("is_allocated failed: %s\n", strerror(-ret));
1695
+ + return 0;
1696
+ + }
1697
+ + sector_num += num;
1698
+ + remaining -= num;
1699
+ + if (ret) {
1700
+ + sum_alloc += num;
1701
+ + }
1702
+ + if (num == 0) {
1703
+ + nb_sectors -= remaining;
1704
+ + remaining = 0;
1705
+ + }
1706
+ + }
1707
+ +
1708
+ + cvtstr(offset, s1, sizeof(s1));
1709
+ +
1710
+ + printf("%d/%d sectors allocated at offset %s\n",
1711
+ + sum_alloc, nb_sectors, s1);
1712
+ + return 0;
1713
+ +}
1714
+ +
1715
+ +static const cmdinfo_t alloc_cmd = {
1716
+ + .name = "alloc",
1717
+ + .altname = "a",
1718
+ + .argmin = 1,
1719
+ + .argmax = 2,
1720
+ + .cfunc = alloc_f,
1721
+ + .args = "off [sectors]",
1722
+ + .oneline = "checks if a sector is present in the file",
1723
+ +};
1724
+ +
1725
+ +static int map_f(BlockDriverState *bs, int argc, char **argv)
1726
+ +{
1727
+ + int64_t offset;
1728
+ + int64_t nb_sectors;
1729
+ + char s1[64];
1730
+ + int num, num_checked;
1731
+ + int ret;
1732
+ + const char *retstr;
1733
+ +
1734
+ + offset = 0;
1735
+ + nb_sectors = bs->total_sectors;
1736
+ +
1737
+ + do {
1738
+ + num_checked = MIN(nb_sectors, INT_MAX);
1739
+ + ret = bdrv_is_allocated(bs, offset, num_checked, &num);
1740
+ + retstr = ret ? " allocated" : "not allocated";
1741
+ + cvtstr(offset << 9ULL, s1, sizeof(s1));
1742
+ + printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
1743
+ + offset << 9ULL, num, num_checked, retstr, s1, ret);
1744
+ +
1745
+ + offset += num;
1746
+ + nb_sectors -= num;
1747
+ + } while (offset < bs->total_sectors);
1748
+ +
1749
+ + return 0;
1750
+ +}
1751
+ +
1752
+ +static const cmdinfo_t map_cmd = {
1753
+ + .name = "map",
1754
+ + .argmin = 0,
1755
+ + .argmax = 0,
1756
+ + .cfunc = map_f,
1757
+ + .args = "",
1758
+ + .oneline = "prints the allocated areas of a file",
1759
+ +};
1760
+ +
1761
+ +static int break_f(BlockDriverState *bs, int argc, char **argv)
1762
+ +{
1763
+ + int ret;
1764
+ +
1765
+ + ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]);
1766
+ + if (ret < 0) {
1767
+ + printf("Could not set breakpoint: %s\n", strerror(-ret));
1768
+ + }
1769
+ +
1770
+ + return 0;
1771
+ +}
1772
+ +
1773
+ +static const cmdinfo_t break_cmd = {
1774
+ + .name = "break",
1775
+ + .argmin = 2,
1776
+ + .argmax = 2,
1777
+ + .cfunc = break_f,
1778
+ + .args = "event tag",
1779
+ + .oneline = "sets a breakpoint on event and tags the stopped "
1780
+ + "request as tag",
1781
+ +};
1782
+ +
1783
+ +static int resume_f(BlockDriverState *bs, int argc, char **argv)
1784
+ +{
1785
+ + int ret;
1786
+ +
1787
+ + ret = bdrv_debug_resume(bs, argv[1]);
1788
+ + if (ret < 0) {
1789
+ + printf("Could not resume request: %s\n", strerror(-ret));
1790
+ + }
1791
+ +
1792
+ + return 0;
1793
+ +}
1794
+ +
1795
+ +static const cmdinfo_t resume_cmd = {
1796
+ + .name = "resume",
1797
+ + .argmin = 1,
1798
+ + .argmax = 1,
1799
+ + .cfunc = resume_f,
1800
+ + .args = "tag",
1801
+ + .oneline = "resumes the request tagged as tag",
1802
+ +};
1803
+ +
1804
+ +static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
1805
+ +{
1806
+ + while (!bdrv_debug_is_suspended(bs, argv[1])) {
1807
+ + qemu_aio_wait();
1808
+ + }
1809
+ +
1810
+ + return 0;
1811
+ +}
1812
+ +
1813
+ +static const cmdinfo_t wait_break_cmd = {
1814
+ + .name = "wait_break",
1815
+ + .argmin = 1,
1816
+ + .argmax = 1,
1817
+ + .cfunc = wait_break_f,
1818
+ + .args = "tag",
1819
+ + .oneline = "waits for the suspension of a request",
1820
+ +};
1821
+ +
1822
+ +static int abort_f(BlockDriverState *bs, int argc, char **argv)
1823
+ +{
1824
+ + abort();
1825
+ +}
1826
+ +
1827
+ +static const cmdinfo_t abort_cmd = {
1828
+ + .name = "abort",
1829
+ + .cfunc = abort_f,
1830
+ + .flags = CMD_NOFILE_OK,
1831
+ + .oneline = "simulate a program crash using abort(3)",
1832
+ +};
1833
+ +
1834
+ +static void sleep_cb(void *opaque)
1835
+ +{
1836
+ + bool *expired = opaque;
1837
+ + *expired = true;
1838
+ +}
1839
+ +
1840
+ +static int sleep_f(BlockDriverState *bs, int argc, char **argv)
1841
+ +{
1842
+ + char *endptr;
1843
+ + long ms;
1844
+ + struct QEMUTimer *timer;
1845
+ + bool expired = false;
1846
+ +
1847
+ + ms = strtol(argv[1], &endptr, 0);
1848
+ + if (ms < 0 || *endptr != '\0') {
1849
+ + printf("%s is not a valid number\n", argv[1]);
1850
+ + return 0;
1851
+ + }
1852
+ +
1853
+ + timer = qemu_new_timer_ns(host_clock, sleep_cb, &expired);
1854
+ + qemu_mod_timer(timer, qemu_get_clock_ns(host_clock) + SCALE_MS * ms);
1855
+ +
1856
+ + while (!expired) {
1857
+ + main_loop_wait(false);
1858
+ + }
1859
+ +
1860
+ + qemu_free_timer(timer);
1861
+ +
1862
+ + return 0;
1863
+ +}
1864
+ +
1865
+ +static const cmdinfo_t sleep_cmd = {
1866
+ + .name = "sleep",
1867
+ + .argmin = 1,
1868
+ + .argmax = 1,
1869
+ + .cfunc = sleep_f,
1870
+ + .flags = CMD_NOFILE_OK,
1871
+ + .oneline = "waits for the given value in milliseconds",
1872
+ +};
1873
+ +
1874
+ +
1875
+ +static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
1876
+ +{
1877
+ + if (ct->flags & CMD_FLAG_GLOBAL) {
1878
+ + return 1;
1879
+ + }
1880
+ + if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
1881
+ + fprintf(stderr, "no file open, try 'help open'\n");
1882
+ + return 0;
1883
+ + }
1884
+ + return 1;
1885
+ +}
1886
+ +
1887
+ +static void __attribute((constructor)) init_qemuio_commands(void)
1888
+ +{
1889
+ + /* initialize commands */
1890
+ + help_init();
1891
+ + add_command(&read_cmd);
1892
+ + add_command(&readv_cmd);
1893
+ + add_command(&write_cmd);
1894
+ + add_command(&writev_cmd);
1895
+ + add_command(&multiwrite_cmd);
1896
+ + add_command(&aio_read_cmd);
1897
+ + add_command(&aio_write_cmd);
1898
+ + add_command(&aio_flush_cmd);
1899
+ + add_command(&flush_cmd);
1900
+ + add_command(&truncate_cmd);
1901
+ + add_command(&length_cmd);
1902
+ + add_command(&info_cmd);
1903
+ + add_command(&discard_cmd);
1904
+ + add_command(&alloc_cmd);
1905
+ + add_command(&map_cmd);
1906
+ + add_command(&break_cmd);
1907
+ + add_command(&resume_cmd);
1908
+ + add_command(&wait_break_cmd);
1909
+ + add_command(&abort_cmd);
1910
+ + add_command(&sleep_cmd);
1911
+ +
1912
+ + add_check_command(init_check_command);
1913
+ +}
1914
+ diff --git a/qemu-io.c b/qemu-io.c
1915
+ index c3cc4f3..4f1c808 100644
1916
+ --- a/qemu-io.c
1917
+ +++ b/qemu-io.c
1918
+ @@ -31,1761 +31,8 @@
1919
+ char *progname;
1920
+
1921
+ BlockDriverState *qemuio_bs;
1922
+ -static int misalign;
1923
+
1924
+ -static int64_t cvtnum(const char *s)
1925
+ -{
1926
+ - char *end;
1927
+ - return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
1928
+ -}
1929
+ -
1930
+ -/*
1931
+ - * Parse the pattern argument to various sub-commands.
1932
+ - *
1933
+ - * Because the pattern is used as an argument to memset it must evaluate
1934
+ - * to an unsigned integer that fits into a single byte.
1935
+ - */
1936
+ -static int parse_pattern(const char *arg)
1937
+ -{
1938
+ - char *endptr = NULL;
1939
+ - long pattern;
1940
+ -
1941
+ - pattern = strtol(arg, &endptr, 0);
1942
+ - if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
1943
+ - printf("%s is not a valid pattern byte\n", arg);
1944
+ - return -1;
1945
+ - }
1946
+ -
1947
+ - return pattern;
1948
+ -}
1949
+ -
1950
+ -/*
1951
+ - * Memory allocation helpers.
1952
+ - *
1953
+ - * Make sure memory is aligned by default, or purposefully misaligned if
1954
+ - * that is specified on the command line.
1955
+ - */
1956
+ -
1957
+ -#define MISALIGN_OFFSET 16
1958
+ -static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
1959
+ -{
1960
+ - void *buf;
1961
+ -
1962
+ - if (misalign) {
1963
+ - len += MISALIGN_OFFSET;
1964
+ - }
1965
+ - buf = qemu_blockalign(bs, len);
1966
+ - memset(buf, pattern, len);
1967
+ - if (misalign) {
1968
+ - buf += MISALIGN_OFFSET;
1969
+ - }
1970
+ - return buf;
1971
+ -}
1972
+ -
1973
+ -static void qemu_io_free(void *p)
1974
+ -{
1975
+ - if (misalign) {
1976
+ - p -= MISALIGN_OFFSET;
1977
+ - }
1978
+ - qemu_vfree(p);
1979
+ -}
1980
+ -
1981
+ -static void dump_buffer(const void *buffer, int64_t offset, int len)
1982
+ -{
1983
+ - int i, j;
1984
+ - const uint8_t *p;
1985
+ -
1986
+ - for (i = 0, p = buffer; i < len; i += 16) {
1987
+ - const uint8_t *s = p;
1988
+ -
1989
+ - printf("%08" PRIx64 ": ", offset + i);
1990
+ - for (j = 0; j < 16 && i + j < len; j++, p++) {
1991
+ - printf("%02x ", *p);
1992
+ - }
1993
+ - printf(" ");
1994
+ - for (j = 0; j < 16 && i + j < len; j++, s++) {
1995
+ - if (isalnum(*s)) {
1996
+ - printf("%c", *s);
1997
+ - } else {
1998
+ - printf(".");
1999
+ - }
2000
+ - }
2001
+ - printf("\n");
2002
+ - }
2003
+ -}
2004
+ -
2005
+ -static void print_report(const char *op, struct timeval *t, int64_t offset,
2006
+ - int count, int total, int cnt, int Cflag)
2007
+ -{
2008
+ - char s1[64], s2[64], ts[64];
2009
+ -
2010
+ - timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
2011
+ - if (!Cflag) {
2012
+ - cvtstr((double)total, s1, sizeof(s1));
2013
+ - cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
2014
+ - printf("%s %d/%d bytes at offset %" PRId64 "\n",
2015
+ - op, total, count, offset);
2016
+ - printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
2017
+ - s1, cnt, ts, s2, tdiv((double)cnt, *t));
2018
+ - } else {/* bytes,ops,time,bytes/sec,ops/sec */
2019
+ - printf("%d,%d,%s,%.3f,%.3f\n",
2020
+ - total, cnt, ts,
2021
+ - tdiv((double)total, *t),
2022
+ - tdiv((double)cnt, *t));
2023
+ - }
2024
+ -}
2025
+ -
2026
+ -/*
2027
+ - * Parse multiple length statements for vectored I/O, and construct an I/O
2028
+ - * vector matching it.
2029
+ - */
2030
+ -static void *
2031
+ -create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
2032
+ - int pattern)
2033
+ -{
2034
+ - size_t *sizes = g_new0(size_t, nr_iov);
2035
+ - size_t count = 0;
2036
+ - void *buf = NULL;
2037
+ - void *p;
2038
+ - int i;
2039
+ -
2040
+ - for (i = 0; i < nr_iov; i++) {
2041
+ - char *arg = argv[i];
2042
+ - int64_t len;
2043
+ -
2044
+ - len = cvtnum(arg);
2045
+ - if (len < 0) {
2046
+ - printf("non-numeric length argument -- %s\n", arg);
2047
+ - goto fail;
2048
+ - }
2049
+ -
2050
+ - /* should be SIZE_T_MAX, but that doesn't exist */
2051
+ - if (len > INT_MAX) {
2052
+ - printf("too large length argument -- %s\n", arg);
2053
+ - goto fail;
2054
+ - }
2055
+ -
2056
+ - if (len & 0x1ff) {
2057
+ - printf("length argument %" PRId64
2058
+ - " is not sector aligned\n", len);
2059
+ - goto fail;
2060
+ - }
2061
+ -
2062
+ - sizes[i] = len;
2063
+ - count += len;
2064
+ - }
2065
+ -
2066
+ - qemu_iovec_init(qiov, nr_iov);
2067
+ -
2068
+ - buf = p = qemu_io_alloc(bs, count, pattern);
2069
+ -
2070
+ - for (i = 0; i < nr_iov; i++) {
2071
+ - qemu_iovec_add(qiov, p, sizes[i]);
2072
+ - p += sizes[i];
2073
+ - }
2074
+ -
2075
+ -fail:
2076
+ - g_free(sizes);
2077
+ - return buf;
2078
+ -}
2079
+ -
2080
+ -static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
2081
+ - int *total)
2082
+ -{
2083
+ - int ret;
2084
+ -
2085
+ - ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
2086
+ - if (ret < 0) {
2087
+ - return ret;
2088
+ - }
2089
+ - *total = count;
2090
+ - return 1;
2091
+ -}
2092
+ -
2093
+ -static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
2094
+ - int *total)
2095
+ -{
2096
+ - int ret;
2097
+ -
2098
+ - ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
2099
+ - if (ret < 0) {
2100
+ - return ret;
2101
+ - }
2102
+ - *total = count;
2103
+ - return 1;
2104
+ -}
2105
+ -
2106
+ -static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
2107
+ - int *total)
2108
+ -{
2109
+ - *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
2110
+ - if (*total < 0) {
2111
+ - return *total;
2112
+ - }
2113
+ - return 1;
2114
+ -}
2115
+ -
2116
+ -static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
2117
+ - int *total)
2118
+ -{
2119
+ - *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
2120
+ - if (*total < 0) {
2121
+ - return *total;
2122
+ - }
2123
+ - return 1;
2124
+ -}
2125
+ -
2126
+ -typedef struct {
2127
+ - BlockDriverState *bs;
2128
+ - int64_t offset;
2129
+ - int count;
2130
+ - int *total;
2131
+ - int ret;
2132
+ - bool done;
2133
+ -} CoWriteZeroes;
2134
+ -
2135
+ -static void coroutine_fn co_write_zeroes_entry(void *opaque)
2136
+ -{
2137
+ - CoWriteZeroes *data = opaque;
2138
+ -
2139
+ - data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
2140
+ - data->count / BDRV_SECTOR_SIZE, 0);
2141
+ - data->done = true;
2142
+ - if (data->ret < 0) {
2143
+ - *data->total = data->ret;
2144
+ - return;
2145
+ - }
2146
+ -
2147
+ - *data->total = data->count;
2148
+ -}
2149
+ -
2150
+ -static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
2151
+ - int *total)
2152
+ -{
2153
+ - Coroutine *co;
2154
+ - CoWriteZeroes data = {
2155
+ - .bs = bs,
2156
+ - .offset = offset,
2157
+ - .count = count,
2158
+ - .total = total,
2159
+ - .done = false,
2160
+ - };
2161
+ -
2162
+ - co = qemu_coroutine_create(co_write_zeroes_entry);
2163
+ - qemu_coroutine_enter(co, &data);
2164
+ - while (!data.done) {
2165
+ - qemu_aio_wait();
2166
+ - }
2167
+ - if (data.ret < 0) {
2168
+ - return data.ret;
2169
+ - } else {
2170
+ - return 1;
2171
+ - }
2172
+ -}
2173
+ -
2174
+ -static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
2175
+ - int count, int *total)
2176
+ -{
2177
+ - int ret;
2178
+ -
2179
+ - ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
2180
+ - if (ret < 0) {
2181
+ - return ret;
2182
+ - }
2183
+ - *total = count;
2184
+ - return 1;
2185
+ -}
2186
+ -
2187
+ -static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
2188
+ - int count, int *total)
2189
+ -{
2190
+ - *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
2191
+ - if (*total < 0) {
2192
+ - return *total;
2193
+ - }
2194
+ - return 1;
2195
+ -}
2196
+ -
2197
+ -static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
2198
+ - int count, int *total)
2199
+ -{
2200
+ - *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
2201
+ - if (*total < 0) {
2202
+ - return *total;
2203
+ - }
2204
+ - return 1;
2205
+ -}
2206
+ -
2207
+ -#define NOT_DONE 0x7fffffff
2208
+ -static void aio_rw_done(void *opaque, int ret)
2209
+ -{
2210
+ - *(int *)opaque = ret;
2211
+ -}
2212
+ -
2213
+ -static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
2214
+ - int64_t offset, int *total)
2215
+ -{
2216
+ - int async_ret = NOT_DONE;
2217
+ -
2218
+ - bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
2219
+ - aio_rw_done, &async_ret);
2220
+ - while (async_ret == NOT_DONE) {
2221
+ - main_loop_wait(false);
2222
+ - }
2223
+ -
2224
+ - *total = qiov->size;
2225
+ - return async_ret < 0 ? async_ret : 1;
2226
+ -}
2227
+ -
2228
+ -static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
2229
+ - int64_t offset, int *total)
2230
+ -{
2231
+ - int async_ret = NOT_DONE;
2232
+ -
2233
+ - bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
2234
+ - aio_rw_done, &async_ret);
2235
+ - while (async_ret == NOT_DONE) {
2236
+ - main_loop_wait(false);
2237
+ - }
2238
+ -
2239
+ - *total = qiov->size;
2240
+ - return async_ret < 0 ? async_ret : 1;
2241
+ -}
2242
+ -
2243
+ -struct multiwrite_async_ret {
2244
+ - int num_done;
2245
+ - int error;
2246
+ -};
2247
+ -
2248
+ -static void multiwrite_cb(void *opaque, int ret)
2249
+ -{
2250
+ - struct multiwrite_async_ret *async_ret = opaque;
2251
+ -
2252
+ - async_ret->num_done++;
2253
+ - if (ret < 0) {
2254
+ - async_ret->error = ret;
2255
+ - }
2256
+ -}
2257
+ -
2258
+ -static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
2259
+ - int num_reqs, int *total)
2260
+ -{
2261
+ - int i, ret;
2262
+ - struct multiwrite_async_ret async_ret = {
2263
+ - .num_done = 0,
2264
+ - .error = 0,
2265
+ - };
2266
+ -
2267
+ - *total = 0;
2268
+ - for (i = 0; i < num_reqs; i++) {
2269
+ - reqs[i].cb = multiwrite_cb;
2270
+ - reqs[i].opaque = &async_ret;
2271
+ - *total += reqs[i].qiov->size;
2272
+ - }
2273
+ -
2274
+ - ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
2275
+ - if (ret < 0) {
2276
+ - return ret;
2277
+ - }
2278
+ -
2279
+ - while (async_ret.num_done < num_reqs) {
2280
+ - main_loop_wait(false);
2281
+ - }
2282
+ -
2283
+ - return async_ret.error < 0 ? async_ret.error : 1;
2284
+ -}
2285
+ -
2286
+ -static void read_help(void)
2287
+ -{
2288
+ - printf(
2289
+ -"\n"
2290
+ -" reads a range of bytes from the given offset\n"
2291
+ -"\n"
2292
+ -" Example:\n"
2293
+ -" 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
2294
+ -"\n"
2295
+ -" Reads a segment of the currently open file, optionally dumping it to the\n"
2296
+ -" standard output stream (with -v option) for subsequent inspection.\n"
2297
+ -" -b, -- read from the VM state rather than the virtual disk\n"
2298
+ -" -C, -- report statistics in a machine parsable format\n"
2299
+ -" -l, -- length for pattern verification (only with -P)\n"
2300
+ -" -p, -- use bdrv_pread to read the file\n"
2301
+ -" -P, -- use a pattern to verify read data\n"
2302
+ -" -q, -- quiet mode, do not show I/O statistics\n"
2303
+ -" -s, -- start offset for pattern verification (only with -P)\n"
2304
+ -" -v, -- dump buffer to standard output\n"
2305
+ -"\n");
2306
+ -}
2307
+ -
2308
+ -static int read_f(BlockDriverState *bs, int argc, char **argv);
2309
+ -
2310
+ -static const cmdinfo_t read_cmd = {
2311
+ - .name = "read",
2312
+ - .altname = "r",
2313
+ - .cfunc = read_f,
2314
+ - .argmin = 2,
2315
+ - .argmax = -1,
2316
+ - .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
2317
+ - .oneline = "reads a number of bytes at a specified offset",
2318
+ - .help = read_help,
2319
+ -};
2320
+ -
2321
+ -static int read_f(BlockDriverState *bs, int argc, char **argv)
2322
+ -{
2323
+ - struct timeval t1, t2;
2324
+ - int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
2325
+ - int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
2326
+ - int c, cnt;
2327
+ - char *buf;
2328
+ - int64_t offset;
2329
+ - int count;
2330
+ - /* Some compilers get confused and warn if this is not initialized. */
2331
+ - int total = 0;
2332
+ - int pattern = 0, pattern_offset = 0, pattern_count = 0;
2333
+ -
2334
+ - while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
2335
+ - switch (c) {
2336
+ - case 'b':
2337
+ - bflag = 1;
2338
+ - break;
2339
+ - case 'C':
2340
+ - Cflag = 1;
2341
+ - break;
2342
+ - case 'l':
2343
+ - lflag = 1;
2344
+ - pattern_count = cvtnum(optarg);
2345
+ - if (pattern_count < 0) {
2346
+ - printf("non-numeric length argument -- %s\n", optarg);
2347
+ - return 0;
2348
+ - }
2349
+ - break;
2350
+ - case 'p':
2351
+ - pflag = 1;
2352
+ - break;
2353
+ - case 'P':
2354
+ - Pflag = 1;
2355
+ - pattern = parse_pattern(optarg);
2356
+ - if (pattern < 0) {
2357
+ - return 0;
2358
+ - }
2359
+ - break;
2360
+ - case 'q':
2361
+ - qflag = 1;
2362
+ - break;
2363
+ - case 's':
2364
+ - sflag = 1;
2365
+ - pattern_offset = cvtnum(optarg);
2366
+ - if (pattern_offset < 0) {
2367
+ - printf("non-numeric length argument -- %s\n", optarg);
2368
+ - return 0;
2369
+ - }
2370
+ - break;
2371
+ - case 'v':
2372
+ - vflag = 1;
2373
+ - break;
2374
+ - default:
2375
+ - return command_usage(&read_cmd);
2376
+ - }
2377
+ - }
2378
+ -
2379
+ - if (optind != argc - 2) {
2380
+ - return command_usage(&read_cmd);
2381
+ - }
2382
+ -
2383
+ - if (bflag && pflag) {
2384
+ - printf("-b and -p cannot be specified at the same time\n");
2385
+ - return 0;
2386
+ - }
2387
+ -
2388
+ - offset = cvtnum(argv[optind]);
2389
+ - if (offset < 0) {
2390
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
2391
+ - return 0;
2392
+ - }
2393
+ -
2394
+ - optind++;
2395
+ - count = cvtnum(argv[optind]);
2396
+ - if (count < 0) {
2397
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
2398
+ - return 0;
2399
+ - }
2400
+ -
2401
+ - if (!Pflag && (lflag || sflag)) {
2402
+ - return command_usage(&read_cmd);
2403
+ - }
2404
+ -
2405
+ - if (!lflag) {
2406
+ - pattern_count = count - pattern_offset;
2407
+ - }
2408
+ -
2409
+ - if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) {
2410
+ - printf("pattern verification range exceeds end of read data\n");
2411
+ - return 0;
2412
+ - }
2413
+ -
2414
+ - if (!pflag) {
2415
+ - if (offset & 0x1ff) {
2416
+ - printf("offset %" PRId64 " is not sector aligned\n",
2417
+ - offset);
2418
+ - return 0;
2419
+ - }
2420
+ - if (count & 0x1ff) {
2421
+ - printf("count %d is not sector aligned\n",
2422
+ - count);
2423
+ - return 0;
2424
+ - }
2425
+ - }
2426
+ -
2427
+ - buf = qemu_io_alloc(bs, count, 0xab);
2428
+ -
2429
+ - gettimeofday(&t1, NULL);
2430
+ - if (pflag) {
2431
+ - cnt = do_pread(bs, buf, offset, count, &total);
2432
+ - } else if (bflag) {
2433
+ - cnt = do_load_vmstate(bs, buf, offset, count, &total);
2434
+ - } else {
2435
+ - cnt = do_read(bs, buf, offset, count, &total);
2436
+ - }
2437
+ - gettimeofday(&t2, NULL);
2438
+ -
2439
+ - if (cnt < 0) {
2440
+ - printf("read failed: %s\n", strerror(-cnt));
2441
+ - goto out;
2442
+ - }
2443
+ -
2444
+ - if (Pflag) {
2445
+ - void *cmp_buf = g_malloc(pattern_count);
2446
+ - memset(cmp_buf, pattern, pattern_count);
2447
+ - if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
2448
+ - printf("Pattern verification failed at offset %"
2449
+ - PRId64 ", %d bytes\n",
2450
+ - offset + pattern_offset, pattern_count);
2451
+ - }
2452
+ - g_free(cmp_buf);
2453
+ - }
2454
+ -
2455
+ - if (qflag) {
2456
+ - goto out;
2457
+ - }
2458
+ -
2459
+ - if (vflag) {
2460
+ - dump_buffer(buf, offset, count);
2461
+ - }
2462
+ -
2463
+ - /* Finally, report back -- -C gives a parsable format */
2464
+ - t2 = tsub(t2, t1);
2465
+ - print_report("read", &t2, offset, count, total, cnt, Cflag);
2466
+ -
2467
+ -out:
2468
+ - qemu_io_free(buf);
2469
+ -
2470
+ - return 0;
2471
+ -}
2472
+ -
2473
+ -static void readv_help(void)
2474
+ -{
2475
+ - printf(
2476
+ -"\n"
2477
+ -" reads a range of bytes from the given offset into multiple buffers\n"
2478
+ -"\n"
2479
+ -" Example:\n"
2480
+ -" 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
2481
+ -"\n"
2482
+ -" Reads a segment of the currently open file, optionally dumping it to the\n"
2483
+ -" standard output stream (with -v option) for subsequent inspection.\n"
2484
+ -" Uses multiple iovec buffers if more than one byte range is specified.\n"
2485
+ -" -C, -- report statistics in a machine parsable format\n"
2486
+ -" -P, -- use a pattern to verify read data\n"
2487
+ -" -v, -- dump buffer to standard output\n"
2488
+ -" -q, -- quiet mode, do not show I/O statistics\n"
2489
+ -"\n");
2490
+ -}
2491
+ -
2492
+ -static int readv_f(BlockDriverState *bs, int argc, char **argv);
2493
+ -
2494
+ -static const cmdinfo_t readv_cmd = {
2495
+ - .name = "readv",
2496
+ - .cfunc = readv_f,
2497
+ - .argmin = 2,
2498
+ - .argmax = -1,
2499
+ - .args = "[-Cqv] [-P pattern ] off len [len..]",
2500
+ - .oneline = "reads a number of bytes at a specified offset",
2501
+ - .help = readv_help,
2502
+ -};
2503
+ -
2504
+ -static int readv_f(BlockDriverState *bs, int argc, char **argv)
2505
+ -{
2506
+ - struct timeval t1, t2;
2507
+ - int Cflag = 0, qflag = 0, vflag = 0;
2508
+ - int c, cnt;
2509
+ - char *buf;
2510
+ - int64_t offset;
2511
+ - /* Some compilers get confused and warn if this is not initialized. */
2512
+ - int total = 0;
2513
+ - int nr_iov;
2514
+ - QEMUIOVector qiov;
2515
+ - int pattern = 0;
2516
+ - int Pflag = 0;
2517
+ -
2518
+ - while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
2519
+ - switch (c) {
2520
+ - case 'C':
2521
+ - Cflag = 1;
2522
+ - break;
2523
+ - case 'P':
2524
+ - Pflag = 1;
2525
+ - pattern = parse_pattern(optarg);
2526
+ - if (pattern < 0) {
2527
+ - return 0;
2528
+ - }
2529
+ - break;
2530
+ - case 'q':
2531
+ - qflag = 1;
2532
+ - break;
2533
+ - case 'v':
2534
+ - vflag = 1;
2535
+ - break;
2536
+ - default:
2537
+ - return command_usage(&readv_cmd);
2538
+ - }
2539
+ - }
2540
+ -
2541
+ - if (optind > argc - 2) {
2542
+ - return command_usage(&readv_cmd);
2543
+ - }
2544
+ -
2545
+ -
2546
+ - offset = cvtnum(argv[optind]);
2547
+ - if (offset < 0) {
2548
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
2549
+ - return 0;
2550
+ - }
2551
+ - optind++;
2552
+ -
2553
+ - if (offset & 0x1ff) {
2554
+ - printf("offset %" PRId64 " is not sector aligned\n",
2555
+ - offset);
2556
+ - return 0;
2557
+ - }
2558
+ -
2559
+ - nr_iov = argc - optind;
2560
+ - buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
2561
+ - if (buf == NULL) {
2562
+ - return 0;
2563
+ - }
2564
+ -
2565
+ - gettimeofday(&t1, NULL);
2566
+ - cnt = do_aio_readv(bs, &qiov, offset, &total);
2567
+ - gettimeofday(&t2, NULL);
2568
+ -
2569
+ - if (cnt < 0) {
2570
+ - printf("readv failed: %s\n", strerror(-cnt));
2571
+ - goto out;
2572
+ - }
2573
+ -
2574
+ - if (Pflag) {
2575
+ - void *cmp_buf = g_malloc(qiov.size);
2576
+ - memset(cmp_buf, pattern, qiov.size);
2577
+ - if (memcmp(buf, cmp_buf, qiov.size)) {
2578
+ - printf("Pattern verification failed at offset %"
2579
+ - PRId64 ", %zd bytes\n", offset, qiov.size);
2580
+ - }
2581
+ - g_free(cmp_buf);
2582
+ - }
2583
+ -
2584
+ - if (qflag) {
2585
+ - goto out;
2586
+ - }
2587
+ -
2588
+ - if (vflag) {
2589
+ - dump_buffer(buf, offset, qiov.size);
2590
+ - }
2591
+ -
2592
+ - /* Finally, report back -- -C gives a parsable format */
2593
+ - t2 = tsub(t2, t1);
2594
+ - print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
2595
+ -
2596
+ -out:
2597
+ - qemu_iovec_destroy(&qiov);
2598
+ - qemu_io_free(buf);
2599
+ - return 0;
2600
+ -}
2601
+ -
2602
+ -static void write_help(void)
2603
+ -{
2604
+ - printf(
2605
+ -"\n"
2606
+ -" writes a range of bytes from the given offset\n"
2607
+ -"\n"
2608
+ -" Example:\n"
2609
+ -" 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
2610
+ -"\n"
2611
+ -" Writes into a segment of the currently open file, using a buffer\n"
2612
+ -" filled with a set pattern (0xcdcdcdcd).\n"
2613
+ -" -b, -- write to the VM state rather than the virtual disk\n"
2614
+ -" -c, -- write compressed data with bdrv_write_compressed\n"
2615
+ -" -p, -- use bdrv_pwrite to write the file\n"
2616
+ -" -P, -- use different pattern to fill file\n"
2617
+ -" -C, -- report statistics in a machine parsable format\n"
2618
+ -" -q, -- quiet mode, do not show I/O statistics\n"
2619
+ -" -z, -- write zeroes using bdrv_co_write_zeroes\n"
2620
+ -"\n");
2621
+ -}
2622
+ -
2623
+ -static int write_f(BlockDriverState *bs, int argc, char **argv);
2624
+ -
2625
+ -static const cmdinfo_t write_cmd = {
2626
+ - .name = "write",
2627
+ - .altname = "w",
2628
+ - .cfunc = write_f,
2629
+ - .argmin = 2,
2630
+ - .argmax = -1,
2631
+ - .args = "[-bcCpqz] [-P pattern ] off len",
2632
+ - .oneline = "writes a number of bytes at a specified offset",
2633
+ - .help = write_help,
2634
+ -};
2635
+ -
2636
+ -static int write_f(BlockDriverState *bs, int argc, char **argv)
2637
+ -{
2638
+ - struct timeval t1, t2;
2639
+ - int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
2640
+ - int cflag = 0;
2641
+ - int c, cnt;
2642
+ - char *buf = NULL;
2643
+ - int64_t offset;
2644
+ - int count;
2645
+ - /* Some compilers get confused and warn if this is not initialized. */
2646
+ - int total = 0;
2647
+ - int pattern = 0xcd;
2648
+ -
2649
+ - while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
2650
+ - switch (c) {
2651
+ - case 'b':
2652
+ - bflag = 1;
2653
+ - break;
2654
+ - case 'c':
2655
+ - cflag = 1;
2656
+ - break;
2657
+ - case 'C':
2658
+ - Cflag = 1;
2659
+ - break;
2660
+ - case 'p':
2661
+ - pflag = 1;
2662
+ - break;
2663
+ - case 'P':
2664
+ - Pflag = 1;
2665
+ - pattern = parse_pattern(optarg);
2666
+ - if (pattern < 0) {
2667
+ - return 0;
2668
+ - }
2669
+ - break;
2670
+ - case 'q':
2671
+ - qflag = 1;
2672
+ - break;
2673
+ - case 'z':
2674
+ - zflag = 1;
2675
+ - break;
2676
+ - default:
2677
+ - return command_usage(&write_cmd);
2678
+ - }
2679
+ - }
2680
+ -
2681
+ - if (optind != argc - 2) {
2682
+ - return command_usage(&write_cmd);
2683
+ - }
2684
+ -
2685
+ - if (bflag + pflag + zflag > 1) {
2686
+ - printf("-b, -p, or -z cannot be specified at the same time\n");
2687
+ - return 0;
2688
+ - }
2689
+ -
2690
+ - if (zflag && Pflag) {
2691
+ - printf("-z and -P cannot be specified at the same time\n");
2692
+ - return 0;
2693
+ - }
2694
+ -
2695
+ - offset = cvtnum(argv[optind]);
2696
+ - if (offset < 0) {
2697
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
2698
+ - return 0;
2699
+ - }
2700
+ -
2701
+ - optind++;
2702
+ - count = cvtnum(argv[optind]);
2703
+ - if (count < 0) {
2704
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
2705
+ - return 0;
2706
+ - }
2707
+ -
2708
+ - if (!pflag) {
2709
+ - if (offset & 0x1ff) {
2710
+ - printf("offset %" PRId64 " is not sector aligned\n",
2711
+ - offset);
2712
+ - return 0;
2713
+ - }
2714
+ -
2715
+ - if (count & 0x1ff) {
2716
+ - printf("count %d is not sector aligned\n",
2717
+ - count);
2718
+ - return 0;
2719
+ - }
2720
+ - }
2721
+ -
2722
+ - if (!zflag) {
2723
+ - buf = qemu_io_alloc(bs, count, pattern);
2724
+ - }
2725
+ -
2726
+ - gettimeofday(&t1, NULL);
2727
+ - if (pflag) {
2728
+ - cnt = do_pwrite(bs, buf, offset, count, &total);
2729
+ - } else if (bflag) {
2730
+ - cnt = do_save_vmstate(bs, buf, offset, count, &total);
2731
+ - } else if (zflag) {
2732
+ - cnt = do_co_write_zeroes(bs, offset, count, &total);
2733
+ - } else if (cflag) {
2734
+ - cnt = do_write_compressed(bs, buf, offset, count, &total);
2735
+ - } else {
2736
+ - cnt = do_write(bs, buf, offset, count, &total);
2737
+ - }
2738
+ - gettimeofday(&t2, NULL);
2739
+ -
2740
+ - if (cnt < 0) {
2741
+ - printf("write failed: %s\n", strerror(-cnt));
2742
+ - goto out;
2743
+ - }
2744
+ -
2745
+ - if (qflag) {
2746
+ - goto out;
2747
+ - }
2748
+ -
2749
+ - /* Finally, report back -- -C gives a parsable format */
2750
+ - t2 = tsub(t2, t1);
2751
+ - print_report("wrote", &t2, offset, count, total, cnt, Cflag);
2752
+ -
2753
+ -out:
2754
+ - if (!zflag) {
2755
+ - qemu_io_free(buf);
2756
+ - }
2757
+ -
2758
+ - return 0;
2759
+ -}
2760
+ -
2761
+ -static void
2762
+ -writev_help(void)
2763
+ -{
2764
+ - printf(
2765
+ -"\n"
2766
+ -" writes a range of bytes from the given offset source from multiple buffers\n"
2767
+ -"\n"
2768
+ -" Example:\n"
2769
+ -" 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
2770
+ -"\n"
2771
+ -" Writes into a segment of the currently open file, using a buffer\n"
2772
+ -" filled with a set pattern (0xcdcdcdcd).\n"
2773
+ -" -P, -- use different pattern to fill file\n"
2774
+ -" -C, -- report statistics in a machine parsable format\n"
2775
+ -" -q, -- quiet mode, do not show I/O statistics\n"
2776
+ -"\n");
2777
+ -}
2778
+ -
2779
+ -static int writev_f(BlockDriverState *bs, int argc, char **argv);
2780
+ -
2781
+ -static const cmdinfo_t writev_cmd = {
2782
+ - .name = "writev",
2783
+ - .cfunc = writev_f,
2784
+ - .argmin = 2,
2785
+ - .argmax = -1,
2786
+ - .args = "[-Cq] [-P pattern ] off len [len..]",
2787
+ - .oneline = "writes a number of bytes at a specified offset",
2788
+ - .help = writev_help,
2789
+ -};
2790
+ -
2791
+ -static int writev_f(BlockDriverState *bs, int argc, char **argv)
2792
+ -{
2793
+ - struct timeval t1, t2;
2794
+ - int Cflag = 0, qflag = 0;
2795
+ - int c, cnt;
2796
+ - char *buf;
2797
+ - int64_t offset;
2798
+ - /* Some compilers get confused and warn if this is not initialized. */
2799
+ - int total = 0;
2800
+ - int nr_iov;
2801
+ - int pattern = 0xcd;
2802
+ - QEMUIOVector qiov;
2803
+ -
2804
+ - while ((c = getopt(argc, argv, "CqP:")) != EOF) {
2805
+ - switch (c) {
2806
+ - case 'C':
2807
+ - Cflag = 1;
2808
+ - break;
2809
+ - case 'q':
2810
+ - qflag = 1;
2811
+ - break;
2812
+ - case 'P':
2813
+ - pattern = parse_pattern(optarg);
2814
+ - if (pattern < 0) {
2815
+ - return 0;
2816
+ - }
2817
+ - break;
2818
+ - default:
2819
+ - return command_usage(&writev_cmd);
2820
+ - }
2821
+ - }
2822
+ -
2823
+ - if (optind > argc - 2) {
2824
+ - return command_usage(&writev_cmd);
2825
+ - }
2826
+ -
2827
+ - offset = cvtnum(argv[optind]);
2828
+ - if (offset < 0) {
2829
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
2830
+ - return 0;
2831
+ - }
2832
+ - optind++;
2833
+ -
2834
+ - if (offset & 0x1ff) {
2835
+ - printf("offset %" PRId64 " is not sector aligned\n",
2836
+ - offset);
2837
+ - return 0;
2838
+ - }
2839
+ -
2840
+ - nr_iov = argc - optind;
2841
+ - buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
2842
+ - if (buf == NULL) {
2843
+ - return 0;
2844
+ - }
2845
+ -
2846
+ - gettimeofday(&t1, NULL);
2847
+ - cnt = do_aio_writev(bs, &qiov, offset, &total);
2848
+ - gettimeofday(&t2, NULL);
2849
+ -
2850
+ - if (cnt < 0) {
2851
+ - printf("writev failed: %s\n", strerror(-cnt));
2852
+ - goto out;
2853
+ - }
2854
+ -
2855
+ - if (qflag) {
2856
+ - goto out;
2857
+ - }
2858
+ -
2859
+ - /* Finally, report back -- -C gives a parsable format */
2860
+ - t2 = tsub(t2, t1);
2861
+ - print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
2862
+ -out:
2863
+ - qemu_iovec_destroy(&qiov);
2864
+ - qemu_io_free(buf);
2865
+ - return 0;
2866
+ -}
2867
+ -
2868
+ -static void multiwrite_help(void)
2869
+ -{
2870
+ - printf(
2871
+ -"\n"
2872
+ -" writes a range of bytes from the given offset source from multiple buffers,\n"
2873
+ -" in a batch of requests that may be merged by qemu\n"
2874
+ -"\n"
2875
+ -" Example:\n"
2876
+ -" 'multiwrite 512 1k 1k ; 4k 1k'\n"
2877
+ -" writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
2878
+ -"\n"
2879
+ -" Writes into a segment of the currently open file, using a buffer\n"
2880
+ -" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
2881
+ -" by one for each request contained in the multiwrite command.\n"
2882
+ -" -P, -- use different pattern to fill file\n"
2883
+ -" -C, -- report statistics in a machine parsable format\n"
2884
+ -" -q, -- quiet mode, do not show I/O statistics\n"
2885
+ -"\n");
2886
+ -}
2887
+ -
2888
+ -static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
2889
+ -
2890
+ -static const cmdinfo_t multiwrite_cmd = {
2891
+ - .name = "multiwrite",
2892
+ - .cfunc = multiwrite_f,
2893
+ - .argmin = 2,
2894
+ - .argmax = -1,
2895
+ - .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
2896
+ - .oneline = "issues multiple write requests at once",
2897
+ - .help = multiwrite_help,
2898
+ -};
2899
+ -
2900
+ -static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
2901
+ -{
2902
+ - struct timeval t1, t2;
2903
+ - int Cflag = 0, qflag = 0;
2904
+ - int c, cnt;
2905
+ - char **buf;
2906
+ - int64_t offset, first_offset = 0;
2907
+ - /* Some compilers get confused and warn if this is not initialized. */
2908
+ - int total = 0;
2909
+ - int nr_iov;
2910
+ - int nr_reqs;
2911
+ - int pattern = 0xcd;
2912
+ - QEMUIOVector *qiovs;
2913
+ - int i;
2914
+ - BlockRequest *reqs;
2915
+ -
2916
+ - while ((c = getopt(argc, argv, "CqP:")) != EOF) {
2917
+ - switch (c) {
2918
+ - case 'C':
2919
+ - Cflag = 1;
2920
+ - break;
2921
+ - case 'q':
2922
+ - qflag = 1;
2923
+ - break;
2924
+ - case 'P':
2925
+ - pattern = parse_pattern(optarg);
2926
+ - if (pattern < 0) {
2927
+ - return 0;
2928
+ - }
2929
+ - break;
2930
+ - default:
2931
+ - return command_usage(&writev_cmd);
2932
+ - }
2933
+ - }
2934
+ -
2935
+ - if (optind > argc - 2) {
2936
+ - return command_usage(&writev_cmd);
2937
+ - }
2938
+ -
2939
+ - nr_reqs = 1;
2940
+ - for (i = optind; i < argc; i++) {
2941
+ - if (!strcmp(argv[i], ";")) {
2942
+ - nr_reqs++;
2943
+ - }
2944
+ - }
2945
+ -
2946
+ - reqs = g_malloc0(nr_reqs * sizeof(*reqs));
2947
+ - buf = g_malloc0(nr_reqs * sizeof(*buf));
2948
+ - qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
2949
+ -
2950
+ - for (i = 0; i < nr_reqs && optind < argc; i++) {
2951
+ - int j;
2952
+ -
2953
+ - /* Read the offset of the request */
2954
+ - offset = cvtnum(argv[optind]);
2955
+ - if (offset < 0) {
2956
+ - printf("non-numeric offset argument -- %s\n", argv[optind]);
2957
+ - goto out;
2958
+ - }
2959
+ - optind++;
2960
+ -
2961
+ - if (offset & 0x1ff) {
2962
+ - printf("offset %lld is not sector aligned\n",
2963
+ - (long long)offset);
2964
+ - goto out;
2965
+ - }
2966
+ -
2967
+ - if (i == 0) {
2968
+ - first_offset = offset;
2969
+ - }
2970
+ -
2971
+ - /* Read lengths for qiov entries */
2972
+ - for (j = optind; j < argc; j++) {
2973
+ - if (!strcmp(argv[j], ";")) {
2974
+ - break;
2975
+ - }
2976
+ - }
2977
+ -
2978
+ - nr_iov = j - optind;
2979
+ -
2980
+ - /* Build request */
2981
+ - buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
2982
+ - if (buf[i] == NULL) {
2983
+ - goto out;
2984
+ - }
2985
+ -
2986
+ - reqs[i].qiov = &qiovs[i];
2987
+ - reqs[i].sector = offset >> 9;
2988
+ - reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
2989
+ -
2990
+ - optind = j + 1;
2991
+ -
2992
+ - pattern++;
2993
+ - }
2994
+ -
2995
+ - /* If there were empty requests at the end, ignore them */
2996
+ - nr_reqs = i;
2997
+ -
2998
+ - gettimeofday(&t1, NULL);
2999
+ - cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
3000
+ - gettimeofday(&t2, NULL);
3001
+ -
3002
+ - if (cnt < 0) {
3003
+ - printf("aio_multiwrite failed: %s\n", strerror(-cnt));
3004
+ - goto out;
3005
+ - }
3006
+ -
3007
+ - if (qflag) {
3008
+ - goto out;
3009
+ - }
3010
+ -
3011
+ - /* Finally, report back -- -C gives a parsable format */
3012
+ - t2 = tsub(t2, t1);
3013
+ - print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
3014
+ -out:
3015
+ - for (i = 0; i < nr_reqs; i++) {
3016
+ - qemu_io_free(buf[i]);
3017
+ - if (reqs[i].qiov != NULL) {
3018
+ - qemu_iovec_destroy(&qiovs[i]);
3019
+ - }
3020
+ - }
3021
+ - g_free(buf);
3022
+ - g_free(reqs);
3023
+ - g_free(qiovs);
3024
+ - return 0;
3025
+ -}
3026
+ -
3027
+ -struct aio_ctx {
3028
+ - QEMUIOVector qiov;
3029
+ - int64_t offset;
3030
+ - char *buf;
3031
+ - int qflag;
3032
+ - int vflag;
3033
+ - int Cflag;
3034
+ - int Pflag;
3035
+ - int pattern;
3036
+ - struct timeval t1;
3037
+ -};
3038
+ -
3039
+ -static void aio_write_done(void *opaque, int ret)
3040
+ -{
3041
+ - struct aio_ctx *ctx = opaque;
3042
+ - struct timeval t2;
3043
+ -
3044
+ - gettimeofday(&t2, NULL);
3045
+ -
3046
+ -
3047
+ - if (ret < 0) {
3048
+ - printf("aio_write failed: %s\n", strerror(-ret));
3049
+ - goto out;
3050
+ - }
3051
+ -
3052
+ - if (ctx->qflag) {
3053
+ - goto out;
3054
+ - }
3055
+ -
3056
+ - /* Finally, report back -- -C gives a parsable format */
3057
+ - t2 = tsub(t2, ctx->t1);
3058
+ - print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
3059
+ - ctx->qiov.size, 1, ctx->Cflag);
3060
+ -out:
3061
+ - qemu_io_free(ctx->buf);
3062
+ - qemu_iovec_destroy(&ctx->qiov);
3063
+ - g_free(ctx);
3064
+ -}
3065
+ -
3066
+ -static void aio_read_done(void *opaque, int ret)
3067
+ -{
3068
+ - struct aio_ctx *ctx = opaque;
3069
+ - struct timeval t2;
3070
+ -
3071
+ - gettimeofday(&t2, NULL);
3072
+ -
3073
+ - if (ret < 0) {
3074
+ - printf("readv failed: %s\n", strerror(-ret));
3075
+ - goto out;
3076
+ - }
3077
+ -
3078
+ - if (ctx->Pflag) {
3079
+ - void *cmp_buf = g_malloc(ctx->qiov.size);
3080
+ -
3081
+ - memset(cmp_buf, ctx->pattern, ctx->qiov.size);
3082
+ - if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
3083
+ - printf("Pattern verification failed at offset %"
3084
+ - PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
3085
+ - }
3086
+ - g_free(cmp_buf);
3087
+ - }
3088
+ -
3089
+ - if (ctx->qflag) {
3090
+ - goto out;
3091
+ - }
3092
+ -
3093
+ - if (ctx->vflag) {
3094
+ - dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
3095
+ - }
3096
+ -
3097
+ - /* Finally, report back -- -C gives a parsable format */
3098
+ - t2 = tsub(t2, ctx->t1);
3099
+ - print_report("read", &t2, ctx->offset, ctx->qiov.size,
3100
+ - ctx->qiov.size, 1, ctx->Cflag);
3101
+ -out:
3102
+ - qemu_io_free(ctx->buf);
3103
+ - qemu_iovec_destroy(&ctx->qiov);
3104
+ - g_free(ctx);
3105
+ -}
3106
+ -
3107
+ -static void aio_read_help(void)
3108
+ -{
3109
+ - printf(
3110
+ -"\n"
3111
+ -" asynchronously reads a range of bytes from the given offset\n"
3112
+ -"\n"
3113
+ -" Example:\n"
3114
+ -" 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
3115
+ -"\n"
3116
+ -" Reads a segment of the currently open file, optionally dumping it to the\n"
3117
+ -" standard output stream (with -v option) for subsequent inspection.\n"
3118
+ -" The read is performed asynchronously and the aio_flush command must be\n"
3119
+ -" used to ensure all outstanding aio requests have been completed.\n"
3120
+ -" -C, -- report statistics in a machine parsable format\n"
3121
+ -" -P, -- use a pattern to verify read data\n"
3122
+ -" -v, -- dump buffer to standard output\n"
3123
+ -" -q, -- quiet mode, do not show I/O statistics\n"
3124
+ -"\n");
3125
+ -}
3126
+ -
3127
+ -static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
3128
+ -
3129
+ -static const cmdinfo_t aio_read_cmd = {
3130
+ - .name = "aio_read",
3131
+ - .cfunc = aio_read_f,
3132
+ - .argmin = 2,
3133
+ - .argmax = -1,
3134
+ - .args = "[-Cqv] [-P pattern ] off len [len..]",
3135
+ - .oneline = "asynchronously reads a number of bytes",
3136
+ - .help = aio_read_help,
3137
+ -};
3138
+ -
3139
+ -static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
3140
+ -{
3141
+ - int nr_iov, c;
3142
+ - struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
3143
+ -
3144
+ - while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
3145
+ - switch (c) {
3146
+ - case 'C':
3147
+ - ctx->Cflag = 1;
3148
+ - break;
3149
+ - case 'P':
3150
+ - ctx->Pflag = 1;
3151
+ - ctx->pattern = parse_pattern(optarg);
3152
+ - if (ctx->pattern < 0) {
3153
+ - g_free(ctx);
3154
+ - return 0;
3155
+ - }
3156
+ - break;
3157
+ - case 'q':
3158
+ - ctx->qflag = 1;
3159
+ - break;
3160
+ - case 'v':
3161
+ - ctx->vflag = 1;
3162
+ - break;
3163
+ - default:
3164
+ - g_free(ctx);
3165
+ - return command_usage(&aio_read_cmd);
3166
+ - }
3167
+ - }
3168
+ -
3169
+ - if (optind > argc - 2) {
3170
+ - g_free(ctx);
3171
+ - return command_usage(&aio_read_cmd);
3172
+ - }
3173
+ -
3174
+ - ctx->offset = cvtnum(argv[optind]);
3175
+ - if (ctx->offset < 0) {
3176
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
3177
+ - g_free(ctx);
3178
+ - return 0;
3179
+ - }
3180
+ - optind++;
3181
+ -
3182
+ - if (ctx->offset & 0x1ff) {
3183
+ - printf("offset %" PRId64 " is not sector aligned\n",
3184
+ - ctx->offset);
3185
+ - g_free(ctx);
3186
+ - return 0;
3187
+ - }
3188
+ -
3189
+ - nr_iov = argc - optind;
3190
+ - ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
3191
+ - if (ctx->buf == NULL) {
3192
+ - g_free(ctx);
3193
+ - return 0;
3194
+ - }
3195
+ -
3196
+ - gettimeofday(&ctx->t1, NULL);
3197
+ - bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
3198
+ - ctx->qiov.size >> 9, aio_read_done, ctx);
3199
+ - return 0;
3200
+ -}
3201
+ -
3202
+ -static void aio_write_help(void)
3203
+ -{
3204
+ - printf(
3205
+ -"\n"
3206
+ -" asynchronously writes a range of bytes from the given offset source\n"
3207
+ -" from multiple buffers\n"
3208
+ -"\n"
3209
+ -" Example:\n"
3210
+ -" 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
3211
+ -"\n"
3212
+ -" Writes into a segment of the currently open file, using a buffer\n"
3213
+ -" filled with a set pattern (0xcdcdcdcd).\n"
3214
+ -" The write is performed asynchronously and the aio_flush command must be\n"
3215
+ -" used to ensure all outstanding aio requests have been completed.\n"
3216
+ -" -P, -- use different pattern to fill file\n"
3217
+ -" -C, -- report statistics in a machine parsable format\n"
3218
+ -" -q, -- quiet mode, do not show I/O statistics\n"
3219
+ -"\n");
3220
+ -}
3221
+ -
3222
+ -static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
3223
+ -
3224
+ -static const cmdinfo_t aio_write_cmd = {
3225
+ - .name = "aio_write",
3226
+ - .cfunc = aio_write_f,
3227
+ - .argmin = 2,
3228
+ - .argmax = -1,
3229
+ - .args = "[-Cq] [-P pattern ] off len [len..]",
3230
+ - .oneline = "asynchronously writes a number of bytes",
3231
+ - .help = aio_write_help,
3232
+ -};
3233
+ -
3234
+ -static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
3235
+ -{
3236
+ - int nr_iov, c;
3237
+ - int pattern = 0xcd;
3238
+ - struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
3239
+ -
3240
+ - while ((c = getopt(argc, argv, "CqP:")) != EOF) {
3241
+ - switch (c) {
3242
+ - case 'C':
3243
+ - ctx->Cflag = 1;
3244
+ - break;
3245
+ - case 'q':
3246
+ - ctx->qflag = 1;
3247
+ - break;
3248
+ - case 'P':
3249
+ - pattern = parse_pattern(optarg);
3250
+ - if (pattern < 0) {
3251
+ - g_free(ctx);
3252
+ - return 0;
3253
+ - }
3254
+ - break;
3255
+ - default:
3256
+ - g_free(ctx);
3257
+ - return command_usage(&aio_write_cmd);
3258
+ - }
3259
+ - }
3260
+ -
3261
+ - if (optind > argc - 2) {
3262
+ - g_free(ctx);
3263
+ - return command_usage(&aio_write_cmd);
3264
+ - }
3265
+ -
3266
+ - ctx->offset = cvtnum(argv[optind]);
3267
+ - if (ctx->offset < 0) {
3268
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
3269
+ - g_free(ctx);
3270
+ - return 0;
3271
+ - }
3272
+ - optind++;
3273
+ -
3274
+ - if (ctx->offset & 0x1ff) {
3275
+ - printf("offset %" PRId64 " is not sector aligned\n",
3276
+ - ctx->offset);
3277
+ - g_free(ctx);
3278
+ - return 0;
3279
+ - }
3280
+ -
3281
+ - nr_iov = argc - optind;
3282
+ - ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
3283
+ - if (ctx->buf == NULL) {
3284
+ - g_free(ctx);
3285
+ - return 0;
3286
+ - }
3287
+ -
3288
+ - gettimeofday(&ctx->t1, NULL);
3289
+ - bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
3290
+ - ctx->qiov.size >> 9, aio_write_done, ctx);
3291
+ - return 0;
3292
+ -}
3293
+ -
3294
+ -static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
3295
+ -{
3296
+ - bdrv_drain_all();
3297
+ - return 0;
3298
+ -}
3299
+ -
3300
+ -static const cmdinfo_t aio_flush_cmd = {
3301
+ - .name = "aio_flush",
3302
+ - .cfunc = aio_flush_f,
3303
+ - .oneline = "completes all outstanding aio requests"
3304
+ -};
3305
+ -
3306
+ -static int flush_f(BlockDriverState *bs, int argc, char **argv)
3307
+ -{
3308
+ - bdrv_flush(bs);
3309
+ - return 0;
3310
+ -}
3311
+ -
3312
+ -static const cmdinfo_t flush_cmd = {
3313
+ - .name = "flush",
3314
+ - .altname = "f",
3315
+ - .cfunc = flush_f,
3316
+ - .oneline = "flush all in-core file state to disk",
3317
+ -};
3318
+ -
3319
+ -static int truncate_f(BlockDriverState *bs, int argc, char **argv)
3320
+ -{
3321
+ - int64_t offset;
3322
+ - int ret;
3323
+ -
3324
+ - offset = cvtnum(argv[1]);
3325
+ - if (offset < 0) {
3326
+ - printf("non-numeric truncate argument -- %s\n", argv[1]);
3327
+ - return 0;
3328
+ - }
3329
+ -
3330
+ - ret = bdrv_truncate(bs, offset);
3331
+ - if (ret < 0) {
3332
+ - printf("truncate: %s\n", strerror(-ret));
3333
+ - return 0;
3334
+ - }
3335
+ -
3336
+ - return 0;
3337
+ -}
3338
+ -
3339
+ -static const cmdinfo_t truncate_cmd = {
3340
+ - .name = "truncate",
3341
+ - .altname = "t",
3342
+ - .cfunc = truncate_f,
3343
+ - .argmin = 1,
3344
+ - .argmax = 1,
3345
+ - .args = "off",
3346
+ - .oneline = "truncates the current file at the given offset",
3347
+ -};
3348
+ -
3349
+ -static int length_f(BlockDriverState *bs, int argc, char **argv)
3350
+ -{
3351
+ - int64_t size;
3352
+ - char s1[64];
3353
+ -
3354
+ - size = bdrv_getlength(bs);
3355
+ - if (size < 0) {
3356
+ - printf("getlength: %s\n", strerror(-size));
3357
+ - return 0;
3358
+ - }
3359
+ -
3360
+ - cvtstr(size, s1, sizeof(s1));
3361
+ - printf("%s\n", s1);
3362
+ - return 0;
3363
+ -}
3364
+ -
3365
+ -
3366
+ -static const cmdinfo_t length_cmd = {
3367
+ - .name = "length",
3368
+ - .altname = "l",
3369
+ - .cfunc = length_f,
3370
+ - .oneline = "gets the length of the current file",
3371
+ -};
3372
+ -
3373
+ -
3374
+ -static int info_f(BlockDriverState *bs, int argc, char **argv)
3375
+ -{
3376
+ - BlockDriverInfo bdi;
3377
+ - ImageInfoSpecific *spec_info;
3378
+ - char s1[64], s2[64];
3379
+ - int ret;
3380
+ -
3381
+ - if (bs->drv && bs->drv->format_name) {
3382
+ - printf("format name: %s\n", bs->drv->format_name);
3383
+ - }
3384
+ - if (bs->drv && bs->drv->protocol_name) {
3385
+ - printf("format name: %s\n", bs->drv->protocol_name);
3386
+ - }
3387
+ -
3388
+ - ret = bdrv_get_info(bs, &bdi);
3389
+ - if (ret) {
3390
+ - return 0;
3391
+ - }
3392
+ -
3393
+ - cvtstr(bdi.cluster_size, s1, sizeof(s1));
3394
+ - cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
3395
+ -
3396
+ - printf("cluster size: %s\n", s1);
3397
+ - printf("vm state offset: %s\n", s2);
3398
+ -
3399
+ - spec_info = bdrv_get_specific_info(bs);
3400
+ - if (spec_info) {
3401
+ - printf("Format specific information:\n");
3402
+ - bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
3403
+ - qapi_free_ImageInfoSpecific(spec_info);
3404
+ - }
3405
+ -
3406
+ - return 0;
3407
+ -}
3408
+ -
3409
+ -
3410
+ -
3411
+ -static const cmdinfo_t info_cmd = {
3412
+ - .name = "info",
3413
+ - .altname = "i",
3414
+ - .cfunc = info_f,
3415
+ - .oneline = "prints information about the current file",
3416
+ -};
3417
+ -
3418
+ -static void discard_help(void)
3419
+ -{
3420
+ - printf(
3421
+ -"\n"
3422
+ -" discards a range of bytes from the given offset\n"
3423
+ -"\n"
3424
+ -" Example:\n"
3425
+ -" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
3426
+ -"\n"
3427
+ -" Discards a segment of the currently open file.\n"
3428
+ -" -C, -- report statistics in a machine parsable format\n"
3429
+ -" -q, -- quiet mode, do not show I/O statistics\n"
3430
+ -"\n");
3431
+ -}
3432
+ -
3433
+ -static int discard_f(BlockDriverState *bs, int argc, char **argv);
3434
+ -
3435
+ -static const cmdinfo_t discard_cmd = {
3436
+ - .name = "discard",
3437
+ - .altname = "d",
3438
+ - .cfunc = discard_f,
3439
+ - .argmin = 2,
3440
+ - .argmax = -1,
3441
+ - .args = "[-Cq] off len",
3442
+ - .oneline = "discards a number of bytes at a specified offset",
3443
+ - .help = discard_help,
3444
+ -};
3445
+ -
3446
+ -static int discard_f(BlockDriverState *bs, int argc, char **argv)
3447
+ -{
3448
+ - struct timeval t1, t2;
3449
+ - int Cflag = 0, qflag = 0;
3450
+ - int c, ret;
3451
+ - int64_t offset;
3452
+ - int count;
3453
+ -
3454
+ - while ((c = getopt(argc, argv, "Cq")) != EOF) {
3455
+ - switch (c) {
3456
+ - case 'C':
3457
+ - Cflag = 1;
3458
+ - break;
3459
+ - case 'q':
3460
+ - qflag = 1;
3461
+ - break;
3462
+ - default:
3463
+ - return command_usage(&discard_cmd);
3464
+ - }
3465
+ - }
3466
+ -
3467
+ - if (optind != argc - 2) {
3468
+ - return command_usage(&discard_cmd);
3469
+ - }
3470
+ -
3471
+ - offset = cvtnum(argv[optind]);
3472
+ - if (offset < 0) {
3473
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
3474
+ - return 0;
3475
+ - }
3476
+ -
3477
+ - optind++;
3478
+ - count = cvtnum(argv[optind]);
3479
+ - if (count < 0) {
3480
+ - printf("non-numeric length argument -- %s\n", argv[optind]);
3481
+ - return 0;
3482
+ - }
3483
+ -
3484
+ - gettimeofday(&t1, NULL);
3485
+ - ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
3486
+ - count >> BDRV_SECTOR_BITS);
3487
+ - gettimeofday(&t2, NULL);
3488
+ -
3489
+ - if (ret < 0) {
3490
+ - printf("discard failed: %s\n", strerror(-ret));
3491
+ - goto out;
3492
+ - }
3493
+ -
3494
+ - /* Finally, report back -- -C gives a parsable format */
3495
+ - if (!qflag) {
3496
+ - t2 = tsub(t2, t1);
3497
+ - print_report("discard", &t2, offset, count, count, 1, Cflag);
3498
+ - }
3499
+ -
3500
+ -out:
3501
+ - return 0;
3502
+ -}
3503
+ -
3504
+ -static int alloc_f(BlockDriverState *bs, int argc, char **argv)
3505
+ -{
3506
+ - int64_t offset, sector_num;
3507
+ - int nb_sectors, remaining;
3508
+ - char s1[64];
3509
+ - int num, sum_alloc;
3510
+ - int ret;
3511
+ -
3512
+ - offset = cvtnum(argv[1]);
3513
+ - if (offset < 0) {
3514
+ - printf("non-numeric offset argument -- %s\n", argv[1]);
3515
+ - return 0;
3516
+ - } else if (offset & 0x1ff) {
3517
+ - printf("offset %" PRId64 " is not sector aligned\n",
3518
+ - offset);
3519
+ - return 0;
3520
+ - }
3521
+ -
3522
+ - if (argc == 3) {
3523
+ - nb_sectors = cvtnum(argv[2]);
3524
+ - if (nb_sectors < 0) {
3525
+ - printf("non-numeric length argument -- %s\n", argv[2]);
3526
+ - return 0;
3527
+ - }
3528
+ - } else {
3529
+ - nb_sectors = 1;
3530
+ - }
3531
+ -
3532
+ - remaining = nb_sectors;
3533
+ - sum_alloc = 0;
3534
+ - sector_num = offset >> 9;
3535
+ - while (remaining) {
3536
+ - ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
3537
+ - if (ret < 0) {
3538
+ - printf("is_allocated failed: %s\n", strerror(-ret));
3539
+ - return 0;
3540
+ - }
3541
+ - sector_num += num;
3542
+ - remaining -= num;
3543
+ - if (ret) {
3544
+ - sum_alloc += num;
3545
+ - }
3546
+ - if (num == 0) {
3547
+ - nb_sectors -= remaining;
3548
+ - remaining = 0;
3549
+ - }
3550
+ - }
3551
+ -
3552
+ - cvtstr(offset, s1, sizeof(s1));
3553
+ -
3554
+ - printf("%d/%d sectors allocated at offset %s\n",
3555
+ - sum_alloc, nb_sectors, s1);
3556
+ - return 0;
3557
+ -}
3558
+ -
3559
+ -static const cmdinfo_t alloc_cmd = {
3560
+ - .name = "alloc",
3561
+ - .altname = "a",
3562
+ - .argmin = 1,
3563
+ - .argmax = 2,
3564
+ - .cfunc = alloc_f,
3565
+ - .args = "off [sectors]",
3566
+ - .oneline = "checks if a sector is present in the file",
3567
+ -};
3568
+ -
3569
+ -static int map_f(BlockDriverState *bs, int argc, char **argv)
3570
+ -{
3571
+ - int64_t offset;
3572
+ - int64_t nb_sectors;
3573
+ - char s1[64];
3574
+ - int num, num_checked;
3575
+ - int ret;
3576
+ - const char *retstr;
3577
+ -
3578
+ - offset = 0;
3579
+ - nb_sectors = bs->total_sectors;
3580
+ -
3581
+ - do {
3582
+ - num_checked = MIN(nb_sectors, INT_MAX);
3583
+ - ret = bdrv_is_allocated(bs, offset, num_checked, &num);
3584
+ - retstr = ret ? " allocated" : "not allocated";
3585
+ - cvtstr(offset << 9ULL, s1, sizeof(s1));
3586
+ - printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
3587
+ - offset << 9ULL, num, num_checked, retstr, s1, ret);
3588
+ -
3589
+ - offset += num;
3590
+ - nb_sectors -= num;
3591
+ - } while (offset < bs->total_sectors);
3592
+ -
3593
+ - return 0;
3594
+ -}
3595
+ -
3596
+ -static const cmdinfo_t map_cmd = {
3597
+ - .name = "map",
3598
+ - .argmin = 0,
3599
+ - .argmax = 0,
3600
+ - .cfunc = map_f,
3601
+ - .args = "",
3602
+ - .oneline = "prints the allocated areas of a file",
3603
+ -};
3604
+ -
3605
+ -static int break_f(BlockDriverState *bs, int argc, char **argv)
3606
+ -{
3607
+ - int ret;
3608
+ -
3609
+ - ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]);
3610
+ - if (ret < 0) {
3611
+ - printf("Could not set breakpoint: %s\n", strerror(-ret));
3612
+ - }
3613
+ -
3614
+ - return 0;
3615
+ -}
3616
+ -
3617
+ -static const cmdinfo_t break_cmd = {
3618
+ - .name = "break",
3619
+ - .argmin = 2,
3620
+ - .argmax = 2,
3621
+ - .cfunc = break_f,
3622
+ - .args = "event tag",
3623
+ - .oneline = "sets a breakpoint on event and tags the stopped "
3624
+ - "request as tag",
3625
+ -};
3626
+ -
3627
+ -static int resume_f(BlockDriverState *bs, int argc, char **argv)
3628
+ -{
3629
+ - int ret;
3630
+ -
3631
+ - ret = bdrv_debug_resume(bs, argv[1]);
3632
+ - if (ret < 0) {
3633
+ - printf("Could not resume request: %s\n", strerror(-ret));
3634
+ - }
3635
+ -
3636
+ - return 0;
3637
+ -}
3638
+ -
3639
+ -static const cmdinfo_t resume_cmd = {
3640
+ - .name = "resume",
3641
+ - .argmin = 1,
3642
+ - .argmax = 1,
3643
+ - .cfunc = resume_f,
3644
+ - .args = "tag",
3645
+ - .oneline = "resumes the request tagged as tag",
3646
+ -};
3647
+ -
3648
+ -static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
3649
+ -{
3650
+ - while (!bdrv_debug_is_suspended(bs, argv[1])) {
3651
+ - qemu_aio_wait();
3652
+ - }
3653
+ -
3654
+ - return 0;
3655
+ -}
3656
+ -
3657
+ -static const cmdinfo_t wait_break_cmd = {
3658
+ - .name = "wait_break",
3659
+ - .argmin = 1,
3660
+ - .argmax = 1,
3661
+ - .cfunc = wait_break_f,
3662
+ - .args = "tag",
3663
+ - .oneline = "waits for the suspension of a request",
3664
+ -};
3665
+ -
3666
+ -static int abort_f(BlockDriverState *bs, int argc, char **argv)
3667
+ -{
3668
+ - abort();
3669
+ -}
3670
+ -
3671
+ -static const cmdinfo_t abort_cmd = {
3672
+ - .name = "abort",
3673
+ - .cfunc = abort_f,
3674
+ - .flags = CMD_NOFILE_OK,
3675
+ - .oneline = "simulate a program crash using abort(3)",
3676
+ -};
3677
+ +extern int qemuio_misalign;
3678
+
3679
+ static int close_f(BlockDriverState *bs, int argc, char **argv)
3680
+ {
3681
+ @@ -1801,45 +48,6 @@ static const cmdinfo_t close_cmd = {
3682
+ .oneline = "close the current open file",
3683
+ };
3684
+
3685
+ -static void sleep_cb(void *opaque)
3686
+ -{
3687
+ - bool *expired = opaque;
3688
+ - *expired = true;
3689
+ -}
3690
+ -
3691
+ -static int sleep_f(BlockDriverState *bs, int argc, char **argv)
3692
+ -{
3693
+ - char *endptr;
3694
+ - long ms;
3695
+ - struct QEMUTimer *timer;
3696
+ - bool expired = false;
3697
+ -
3698
+ - ms = strtol(argv[1], &endptr, 0);
3699
+ - if (ms < 0 || *endptr != '\0') {
3700
+ - printf("%s is not a valid number\n", argv[1]);
3701
+ - return 0;
3702
+ - }
3703
+ -
3704
+ - timer = qemu_new_timer_ns(host_clock, sleep_cb, &expired);
3705
+ - qemu_mod_timer(timer, qemu_get_clock_ns(host_clock) + SCALE_MS * ms);
3706
+ -
3707
+ - while (!expired) {
3708
+ - main_loop_wait(false);
3709
+ - }
3710
+ -
3711
+ - qemu_free_timer(timer);
3712
+ -
3713
+ - return 0;
3714
+ -}
3715
+ -
3716
+ -static const cmdinfo_t sleep_cmd = {
3717
+ - .name = "sleep",
3718
+ - .argmin = 1,
3719
+ - .argmax = 1,
3720
+ - .cfunc = sleep_f,
3721
+ - .flags = CMD_NOFILE_OK,
3722
+ - .oneline = "waits for the given value in milliseconds",
3723
+ -};
3724
+
3725
+ static int openfile(char *name, int flags, int growable, QDict *opts)
3726
+ {
3727
+ @@ -1962,18 +170,6 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
3728
+ return openfile(argv[optind], flags, growable, opts);
3729
+ }
3730
+
3731
+ -static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
3732
+ -{
3733
+ - if (ct->flags & CMD_FLAG_GLOBAL) {
3734
+ - return 1;
3735
+ - }
3736
+ - if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
3737
+ - fprintf(stderr, "no file open, try 'help open'\n");
3738
+ - return 0;
3739
+ - }
3740
+ - return 1;
3741
+ -}
3742
+ -
3743
+ static void usage(const char *name)
3744
+ {
3745
+ printf(
3746
+ @@ -2049,7 +245,7 @@ int main(int argc, char **argv)
3747
+ readonly = 1;
3748
+ break;
3749
+ case 'm':
3750
+ - misalign = 1;
3751
+ + qemuio_misalign = 1;
3752
+ break;
3753
+ case 'g':
3754
+ growable = 1;
3755
+ @@ -2090,31 +286,8 @@ int main(int argc, char **argv)
3756
+
3757
+ /* initialize commands */
3758
+ quit_init();
3759
+ - help_init();
3760
+ add_command(&open_cmd);
3761
+ add_command(&close_cmd);
3762
+ - add_command(&read_cmd);
3763
+ - add_command(&readv_cmd);
3764
+ - add_command(&write_cmd);
3765
+ - add_command(&writev_cmd);
3766
+ - add_command(&multiwrite_cmd);
3767
+ - add_command(&aio_read_cmd);
3768
+ - add_command(&aio_write_cmd);
3769
+ - add_command(&aio_flush_cmd);
3770
+ - add_command(&flush_cmd);
3771
+ - add_command(&truncate_cmd);
3772
+ - add_command(&length_cmd);
3773
+ - add_command(&info_cmd);
3774
+ - add_command(&discard_cmd);
3775
+ - add_command(&alloc_cmd);
3776
+ - add_command(&map_cmd);
3777
+ - add_command(&break_cmd);
3778
+ - add_command(&resume_cmd);
3779
+ - add_command(&wait_break_cmd);
3780
+ - add_command(&abort_cmd);
3781
+ - add_command(&sleep_cmd);
3782
+ -
3783
+ - add_check_command(init_check_command);
3784
+
3785
+ /* open the device */
3786
+ if (!readonly) {
3787
+ --
3788
+ 1.8.3.1
3789
+
SOURCES/kvm-qemu-io-Use-the-qemu-version-for-V.patch ADDED
@@ -0,0 +1,54 @@
1
+ From 883449501b5d87002bb01c2a060cf650acf45d9a Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:34 +0100
4
+ Subject: [PATCH 15/27] qemu-io: Use the qemu version for -V
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-16-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68442
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 15/21] qemu-io: Use the qemu version for -V
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ From: Kevin Wolf <kwolf@redhat.com>
16
+
17
+ Always printing 0.0.1 and never updating the version number wasn't very
18
+ useful. qemu-io is released with qemu, so using the same version number
19
+ makes most sense.
20
+
21
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
23
+ (cherry picked from commit 02da386a2d7a020e80b0aed64769efa9dd42072a)
24
+ Signed-off-by: John Snow <jsnow@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ qemu-io.c | 4 +---
28
+ 1 file changed, 1 insertion(+), 3 deletions(-)
29
+
30
+ diff --git a/qemu-io.c b/qemu-io.c
31
+ index e685808..16b2d8a 100644
32
+ --- a/qemu-io.c
33
+ +++ b/qemu-io.c
34
+ @@ -23,8 +23,6 @@
35
+ #include "trace/control.h"
36
+ #include "qemu/timer.h"
37
+
38
+ -#define VERSION "0.0.1"
39
+ -
40
+ #define CMD_NOFILE_OK 0x01
41
+
42
+ char *progname;
43
+ @@ -418,7 +416,7 @@ int main(int argc, char **argv)
44
+ }
45
+ break;
46
+ case 'V':
47
+ - printf("%s version %s\n", progname, VERSION);
48
+ + printf("%s version %s\n", progname, QEMU_VERSION);
49
+ exit(0);
50
+ case 'h':
51
+ usage(progname);
52
+ --
53
+ 1.8.3.1
54
+
SOURCES/kvm-qemu-io-fix-cvtnum-lval-types.patch ADDED
@@ -0,0 +1,360 @@
1
+ From a5226789eaaedf06f50f2faf14b506c17deb5435 Mon Sep 17 00:00:00 2001
2
+ From: John Snow <jsnow@redhat.com>
3
+ Date: Mon, 23 Nov 2015 17:38:37 +0100
4
+ Subject: [PATCH 18/27] qemu-io: fix cvtnum lval types
5
+
6
+ RH-Author: John Snow <jsnow@redhat.com>
7
+ Message-id: <1448300320-7772-19-git-send-email-jsnow@redhat.com>
8
+ Patchwork-id: 68445
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 18/21] qemu-io: fix cvtnum lval types
10
+ Bugzilla: 1272523
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+
15
+ cvtnum() returns int64_t: we should not be storing this
16
+ result inside of an int.
17
+
18
+ In a few cases, we need an extra sprinkling of error handling
19
+ where we expect to pass this number on towards a function that
20
+ expects something smaller than int64_t.
21
+
22
+ Reported-by: Max Reitz <mreitz@redhat.com>
23
+ Signed-off-by: John Snow <jsnow@redhat.com>
24
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
+ (cherry picked from commit 9b0beaf3de1396a23d5c287283e6f36c4b5d4385)
26
+ Signed-off-by: John Snow <jsnow@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+
29
+ Conflicts:
30
+ qemu-io-cmds.c:
31
+ - Upstream uses blk_xxx commands, while downstream uses bdrv_xxx
32
+ - Fixes to sigraise are not backported.
33
+
34
+ Signed-off-by: John Snow <jsnow@redhat.com>
35
+ ---
36
+ qemu-io-cmds.c | 119 ++++++++++++++++++++++++++++++++++++++++-----------------
37
+ 1 file changed, 84 insertions(+), 35 deletions(-)
38
+
39
+ diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
40
+ index 1f21ce9..95345fe 100644
41
+ --- a/qemu-io-cmds.c
42
+ +++ b/qemu-io-cmds.c
43
+ @@ -282,9 +282,10 @@ static void qemu_io_free(void *p)
44
+ qemu_vfree(p);
45
+ }
46
+
47
+ -static void dump_buffer(const void *buffer, int64_t offset, int len)
48
+ +static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
49
+ {
50
+ - int i, j;
51
+ + uint64_t i;
52
+ + int j;
53
+ const uint8_t *p;
54
+
55
+ for (i = 0, p = buffer; i < len; i += 16) {
56
+ @@ -307,7 +308,7 @@ static void dump_buffer(const void *buffer, int64_t offset, int len)
57
+ }
58
+
59
+ static void print_report(const char *op, struct timeval *t, int64_t offset,
60
+ - int count, int total, int cnt, int Cflag)
61
+ + int64_t count, int64_t total, int cnt, int Cflag)
62
+ {
63
+ char s1[64], s2[64], ts[64];
64
+
65
+ @@ -315,12 +316,12 @@ static void print_report(const char *op, struct timeval *t, int64_t offset,
66
+ if (!Cflag) {
67
+ cvtstr((double)total, s1, sizeof(s1));
68
+ cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
69
+ - printf("%s %d/%d bytes at offset %" PRId64 "\n",
70
+ + printf("%s %"PRId64"/%"PRId64" bytes at offset %" PRId64 "\n",
71
+ op, total, count, offset);
72
+ printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
73
+ s1, cnt, ts, s2, tdiv((double)cnt, *t));
74
+ } else {/* bytes,ops,time,bytes/sec,ops/sec */
75
+ - printf("%d,%d,%s,%.3f,%.3f\n",
76
+ + printf("%"PRId64",%d,%s,%.3f,%.3f\n",
77
+ total, cnt, ts,
78
+ tdiv((double)total, *t),
79
+ tdiv((double)cnt, *t));
80
+ @@ -381,11 +382,15 @@ fail:
81
+ return buf;
82
+ }
83
+
84
+ -static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
85
+ - int *total)
86
+ +static int do_read(BlockDriverState *bs, char *buf, int64_t offset,
87
+ + int64_t count, int64_t *total)
88
+ {
89
+ int ret;
90
+
91
+ + if (count >> 9 > INT_MAX) {
92
+ + return -ERANGE;
93
+ + }
94
+ +
95
+ ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
96
+ if (ret < 0) {
97
+ return ret;
98
+ @@ -394,11 +399,15 @@ static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
99
+ return 1;
100
+ }
101
+
102
+ -static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
103
+ - int *total)
104
+ +static int do_write(BlockDriverState *bs, char *buf, int64_t offset,
105
+ + int64_t count, int64_t *total)
106
+ {
107
+ int ret;
108
+
109
+ + if (count >> 9 > INT_MAX) {
110
+ + return -ERANGE;
111
+ + }
112
+ +
113
+ ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
114
+ if (ret < 0) {
115
+ return ret;
116
+ @@ -407,9 +416,13 @@ static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
117
+ return 1;
118
+ }
119
+
120
+ -static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
121
+ - int *total)
122
+ +static int do_pread(BlockDriverState *bs, char *buf, int64_t offset,
123
+ + int64_t count, int64_t *total)
124
+ {
125
+ + if (count > INT_MAX) {
126
+ + return -ERANGE;
127
+ + }
128
+ +
129
+ *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
130
+ if (*total < 0) {
131
+ return *total;
132
+ @@ -417,9 +430,13 @@ static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
133
+ return 1;
134
+ }
135
+
136
+ -static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
137
+ - int *total)
138
+ +static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset,
139
+ + int64_t count, int64_t *total)
140
+ {
141
+ + if (count > INT_MAX) {
142
+ + return -ERANGE;
143
+ + }
144
+ +
145
+ *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
146
+ if (*total < 0) {
147
+ return *total;
148
+ @@ -430,8 +447,8 @@ static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
149
+ typedef struct {
150
+ BlockDriverState *bs;
151
+ int64_t offset;
152
+ - int count;
153
+ - int *total;
154
+ + int64_t count;
155
+ + int64_t *total;
156
+ int ret;
157
+ bool done;
158
+ } CoWriteZeroes;
159
+ @@ -451,8 +468,8 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
160
+ *data->total = data->count;
161
+ }
162
+
163
+ -static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
164
+ - int *total)
165
+ +static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset,
166
+ + int64_t count, int64_t *total)
167
+ {
168
+ Coroutine *co;
169
+ CoWriteZeroes data = {
170
+ @@ -463,6 +480,10 @@ static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
171
+ .done = false,
172
+ };
173
+
174
+ + if (count >> BDRV_SECTOR_BITS > INT_MAX) {
175
+ + return -ERANGE;
176
+ + }
177
+ +
178
+ co = qemu_coroutine_create(co_write_zeroes_entry);
179
+ qemu_coroutine_enter(co, &data);
180
+ while (!data.done) {
181
+ @@ -476,10 +497,14 @@ static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
182
+ }
183
+
184
+ static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
185
+ - int count, int *total)
186
+ + int64_t count, int64_t *total)
187
+ {
188
+ int ret;
189
+
190
+ + if (count >> 9 > INT_MAX) {
191
+ + return -ERANGE;
192
+ + }
193
+ +
194
+ ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
195
+ if (ret < 0) {
196
+ return ret;
197
+ @@ -489,8 +514,12 @@ static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
198
+ }
199
+
200
+ static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
201
+ - int count, int *total)
202
+ + int64_t count, int64_t *total)
203
+ {
204
+ + if (count > INT_MAX) {
205
+ + return -ERANGE;
206
+ + }
207
+ +
208
+ *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
209
+ if (*total < 0) {
210
+ return *total;
211
+ @@ -499,8 +528,12 @@ static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
212
+ }
213
+
214
+ static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
215
+ - int count, int *total)
216
+ + int64_t count, int64_t *total)
217
+ {
218
+ + if (count > INT_MAX) {
219
+ + return -ERANGE;
220
+ + }
221
+ +
222
+ *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
223
+ if (*total < 0) {
224
+ return *total;
225
+ @@ -630,10 +663,11 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
226
+ int c, cnt;
227
+ char *buf;
228
+ int64_t offset;
229
+ - int count;
230
+ + int64_t count;
231
+ /* Some compilers get confused and warn if this is not initialized. */
232
+ - int total = 0;
233
+ - int pattern = 0, pattern_offset = 0, pattern_count = 0;
234
+ + int64_t total = 0;
235
+ + int pattern = 0;
236
+ + int64_t pattern_offset = 0, pattern_count = 0;
237
+
238
+ while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
239
+ switch (c) {
240
+ @@ -700,6 +734,10 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
241
+ if (count < 0) {
242
+ printf("non-numeric length argument -- %s\n", argv[optind]);
243
+ return 0;
244
+ + } else if (count > SIZE_MAX) {
245
+ + printf("length cannot exceed %" PRIu64 ", given %s\n",
246
+ + (uint64_t) SIZE_MAX, argv[optind]);
247
+ + return 0;
248
+ }
249
+
250
+ if (!Pflag && (lflag || sflag)) {
251
+ @@ -722,7 +760,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
252
+ return 0;
253
+ }
254
+ if (count & 0x1ff) {
255
+ - printf("count %d is not sector aligned\n",
256
+ + printf("count %"PRId64" is not sector aligned\n",
257
+ count);
258
+ return 0;
259
+ }
260
+ @@ -750,7 +788,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
261
+ memset(cmp_buf, pattern, pattern_count);
262
+ if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
263
+ printf("Pattern verification failed at offset %"
264
+ - PRId64 ", %d bytes\n",
265
+ + PRId64 ", %"PRId64" bytes\n",
266
+ offset + pattern_offset, pattern_count);
267
+ }
268
+ g_free(cmp_buf);
269
+ @@ -945,9 +983,9 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
270
+ int c, cnt;
271
+ char *buf = NULL;
272
+ int64_t offset;
273
+ - int count;
274
+ + int64_t count;
275
+ /* Some compilers get confused and warn if this is not initialized. */
276
+ - int total = 0;
277
+ + int64_t total = 0;
278
+ int pattern = 0xcd;
279
+
280
+ while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
281
+ @@ -1007,6 +1045,10 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
282
+ if (count < 0) {
283
+ printf("non-numeric length argument -- %s\n", argv[optind]);
284
+ return 0;
285
+ + } else if (count > SIZE_MAX) {
286
+ + printf("length cannot exceed %" PRIu64 ", given %s\n",
287
+ + (uint64_t) SIZE_MAX, argv[optind]);
288
+ + return 0;
289
+ }
290
+
291
+ if (!pflag) {
292
+ @@ -1017,7 +1059,7 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
293
+ }
294
+
295
+ if (count & 0x1ff) {
296
+ - printf("count %d is not sector aligned\n",
297
+ + printf("count %"PRId64" is not sector aligned\n",
298
+ count);
299
+ return 0;
300
+ }
301
+ @@ -1752,8 +1794,7 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
302
+ struct timeval t1, t2;
303
+ int Cflag = 0, qflag = 0;
304
+ int c, ret;
305
+ - int64_t offset;
306
+ - int count;
307
+ + int64_t offset, count;
308
+
309
+ while ((c = getopt(argc, argv, "Cq")) != EOF) {
310
+ switch (c) {
311
+ @@ -1783,6 +1824,11 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
312
+ if (count < 0) {
313
+ printf("non-numeric length argument -- %s\n", argv[optind]);
314
+ return 0;
315
+ + } else if (count >> BDRV_SECTOR_BITS > INT_MAX) {
316
+ + printf("length cannot exceed %"PRIu64", given %s\n",
317
+ + (uint64_t)INT_MAX << BDRV_SECTOR_BITS,
318
+ + argv[optind]);
319
+ + return 0;
320
+ }
321
+
322
+ gettimeofday(&t1, NULL);
323
+ @@ -1807,11 +1853,10 @@ out:
324
+
325
+ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
326
+ {
327
+ - int64_t offset, sector_num;
328
+ - int nb_sectors, remaining;
329
+ + int64_t offset, sector_num, nb_sectors, remaining;
330
+ char s1[64];
331
+ - int num, sum_alloc;
332
+ - int ret;
333
+ + int num, ret;
334
+ + int64_t sum_alloc;
335
+
336
+ offset = cvtnum(argv[1]);
337
+ if (offset < 0) {
338
+ @@ -1828,6 +1873,10 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
339
+ if (nb_sectors < 0) {
340
+ printf("non-numeric length argument -- %s\n", argv[2]);
341
+ return 0;
342
+ + } else if (nb_sectors > INT_MAX) {
343
+ + printf("length argument cannot exceed %d, given %s\n",
344
+ + INT_MAX, argv[2]);
345
+ + return 0;
346
+ }
347
+ } else {
348
+ nb_sectors = 1;
349
+ @@ -1855,7 +1904,7 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
350
+
351
+ cvtstr(offset, s1, sizeof(s1));
352
+
353
+ - printf("%d/%d sectors allocated at offset %s\n",
354
+ + printf("%"PRId64"/%"PRId64" sectors allocated at offset %s\n",
355
+ sum_alloc, nb_sectors, s1);
356
+ return 0;
357
+ }
358
+ --
359
+ 1.8.3.1
360
+
SOURCES/kvm-qjson-Apply-nesting-limit-more-sanely.patch ADDED
@@ -0,0 +1,46 @@
1
+ From 1f08301adf98c235ccc4e978f809c3f60833452c Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:00 +0200
4
+ Subject: [PATCH 02/16] qjson: Apply nesting limit more sanely
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-4-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71468
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 02/15] qjson: Apply nesting limit more sanely
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ The nesting limit from commit 29c75dd "json-streamer: limit the
16
+ maximum recursion depth and maximum token count" applies separately to
17
+ braces and brackets. This makes no sense. Apply it to their sum,
18
+ because that's actually a measure of recursion depth.
19
+
20
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
21
+ Reviewed-by: Eric Blake <eblake@redhat.com>
22
+ Message-Id: <1448486613-17634-2-git-send-email-armbru@redhat.com>
23
+ (cherry picked from commit 4f2d31fbc0bfdf41feea7d1be49f4f7ffa005534)
24
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ qobject/json-streamer.c | 3 +--
28
+ 1 file changed, 1 insertion(+), 2 deletions(-)
29
+
30
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
31
+ index 1b2f9b1..dced2c7 100644
32
+ --- a/qobject/json-streamer.c
33
+ +++ b/qobject/json-streamer.c
34
+ @@ -64,8 +64,7 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
35
+ parser->bracket_count == 0)) {
36
+ goto out_emit;
37
+ } else if (parser->token_size > MAX_TOKEN_SIZE ||
38
+ - parser->bracket_count > MAX_NESTING ||
39
+ - parser->brace_count > MAX_NESTING) {
40
+ + parser->bracket_count + parser->brace_count > MAX_NESTING) {
41
+ /* Security consideration, we limit total memory allocated per object
42
+ * and the maximum recursion depth that a message can force.
43
+ */
44
+ --
45
+ 1.8.3.1
46
+
SOURCES/kvm-qjson-Convert-to-parser-to-recursive-descent.patch ADDED
@@ -0,0 +1,328 @@
1
+ From 2975abb487a54b49246646db9aa40ee6d1beaa97 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:08 +0200
4
+ Subject: [PATCH 10/16] qjson: Convert to parser to recursive descent
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-12-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71474
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 10/15] qjson: Convert to parser to recursive descent
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ We backtrack in parse_value(), even though JSON is LL(1) and thus can
16
+ be parsed by straightforward recursive descent. Do exactly that.
17
+
18
+ Based on an almost-correct patch from Paolo Bonzini.
19
+
20
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
21
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
22
+ Message-Id: <1448486613-17634-10-git-send-email-armbru@redhat.com>
23
+ Reviewed-by: Eric Blake <eblake@redhat.com>
24
+ (cherry picked from commit d538b25543f4db026bb435066e2403a542522c40)
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+
27
+ Conflicts:
28
+ qobject/json-parser.c
29
+
30
+ Straighforward conflicts because lacking commit fc48ffc "qobject: Use
31
+ 'bool' for qbool", we still use qbool_from_int(), and we lack commit
32
+ e549e71 "json-parser: Accept 'null' in QMP".
33
+
34
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
35
+ ---
36
+ qobject/json-parser.c | 163 ++++++++++++++------------------------------------
37
+ 1 file changed, 46 insertions(+), 117 deletions(-)
38
+
39
+ diff --git a/qobject/json-parser.c b/qobject/json-parser.c
40
+ index 79f4173..b242fba 100644
41
+ --- a/qobject/json-parser.c
42
+ +++ b/qobject/json-parser.c
43
+ @@ -266,23 +266,6 @@ static QObject *parser_context_peek_token(JSONParserContext *ctxt)
44
+ return token;
45
+ }
46
+
47
+ -static JSONParserContext parser_context_save(JSONParserContext *ctxt)
48
+ -{
49
+ - JSONParserContext saved_ctxt = {0};
50
+ - saved_ctxt.tokens.pos = ctxt->tokens.pos;
51
+ - saved_ctxt.tokens.count = ctxt->tokens.count;
52
+ - saved_ctxt.tokens.buf = ctxt->tokens.buf;
53
+ - return saved_ctxt;
54
+ -}
55
+ -
56
+ -static void parser_context_restore(JSONParserContext *ctxt,
57
+ - JSONParserContext saved_ctxt)
58
+ -{
59
+ - ctxt->tokens.pos = saved_ctxt.tokens.pos;
60
+ - ctxt->tokens.count = saved_ctxt.tokens.count;
61
+ - ctxt->tokens.buf = saved_ctxt.tokens.buf;
62
+ -}
63
+ -
64
+ static void tokens_append_from_iter(QObject *obj, void *opaque)
65
+ {
66
+ JSONParserContext *ctxt = opaque;
67
+ @@ -334,7 +317,6 @@ static void parser_context_free(JSONParserContext *ctxt)
68
+ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
69
+ {
70
+ QObject *key = NULL, *token = NULL, *value, *peek;
71
+ - JSONParserContext saved_ctxt = parser_context_save(ctxt);
72
+
73
+ peek = parser_context_peek_token(ctxt);
74
+ if (peek == NULL) {
75
+ @@ -372,7 +354,6 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
76
+ return 0;
77
+
78
+ out:
79
+ - parser_context_restore(ctxt, saved_ctxt);
80
+ qobject_decref(key);
81
+
82
+ return -1;
83
+ @@ -382,16 +363,9 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
84
+ {
85
+ QDict *dict = NULL;
86
+ QObject *token, *peek;
87
+ - JSONParserContext saved_ctxt = parser_context_save(ctxt);
88
+
89
+ token = parser_context_pop_token(ctxt);
90
+ - if (token == NULL) {
91
+ - goto out;
92
+ - }
93
+ -
94
+ - if (token_get_type(token) != JSON_LCURLY) {
95
+ - goto out;
96
+ - }
97
+ + assert(token && token_get_type(token) == JSON_LCURLY);
98
+
99
+ dict = qdict_new();
100
+
101
+ @@ -435,7 +409,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
102
+ return QOBJECT(dict);
103
+
104
+ out:
105
+ - parser_context_restore(ctxt, saved_ctxt);
106
+ QDECREF(dict);
107
+ return NULL;
108
+ }
109
+ @@ -444,16 +417,9 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
110
+ {
111
+ QList *list = NULL;
112
+ QObject *token, *peek;
113
+ - JSONParserContext saved_ctxt = parser_context_save(ctxt);
114
+
115
+ token = parser_context_pop_token(ctxt);
116
+ - if (token == NULL) {
117
+ - goto out;
118
+ - }
119
+ -
120
+ - if (token_get_type(token) != JSON_LSQUARE) {
121
+ - goto out;
122
+ - }
123
+ + assert(token && token_get_type(token) == JSON_LSQUARE);
124
+
125
+ list = qlist_new();
126
+
127
+ @@ -507,107 +473,70 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
128
+ return QOBJECT(list);
129
+
130
+ out:
131
+ - parser_context_restore(ctxt, saved_ctxt);
132
+ QDECREF(list);
133
+ return NULL;
134
+ }
135
+
136
+ static QObject *parse_keyword(JSONParserContext *ctxt)
137
+ {
138
+ - QObject *token, *ret;
139
+ - JSONParserContext saved_ctxt = parser_context_save(ctxt);
140
+ + QObject *token;
141
+ const char *val;
142
+
143
+ token = parser_context_pop_token(ctxt);
144
+ - if (token == NULL) {
145
+ - goto out;
146
+ - }
147
+ -
148
+ - if (token_get_type(token) != JSON_KEYWORD) {
149
+ - goto out;
150
+ - }
151
+ -
152
+ + assert(token && token_get_type(token) == JSON_KEYWORD);
153
+ val = token_get_value(token);
154
+
155
+ if (!strcmp(val, "true")) {
156
+ - ret = QOBJECT(qbool_from_int(true));
157
+ + return QOBJECT(qbool_from_int(true));
158
+ } else if (!strcmp(val, "false")) {
159
+ - ret = QOBJECT(qbool_from_int(false));
160
+ - } else {
161
+ - parse_error(ctxt, token, "invalid keyword '%s'", val);
162
+ - goto out;
163
+ + return QOBJECT(qbool_from_int(false));
164
+ }
165
+ -
166
+ - return ret;
167
+ -
168
+ -out:
169
+ - parser_context_restore(ctxt, saved_ctxt);
170
+ -
171
+ + parse_error(ctxt, token, "invalid keyword '%s'", val);
172
+ return NULL;
173
+ }
174
+
175
+ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
176
+ {
177
+ - QObject *token = NULL, *obj;
178
+ - JSONParserContext saved_ctxt = parser_context_save(ctxt);
179
+ + QObject *token;
180
+ const char *val;
181
+
182
+ if (ap == NULL) {
183
+ - goto out;
184
+ + return NULL;
185
+ }
186
+
187
+ token = parser_context_pop_token(ctxt);
188
+ - if (token == NULL) {
189
+ - goto out;
190
+ - }
191
+ -
192
+ - if (token_get_type(token) != JSON_ESCAPE) {
193
+ - goto out;
194
+ - }
195
+ -
196
+ + assert(token && token_get_type(token) == JSON_ESCAPE);
197
+ val = token_get_value(token);
198
+
199
+ if (!strcmp(val, "%p")) {
200
+ - obj = va_arg(*ap, QObject *);
201
+ + return va_arg(*ap, QObject *);
202
+ } else if (!strcmp(val, "%i")) {
203
+ - obj = QOBJECT(qbool_from_int(va_arg(*ap, int)));
204
+ + return QOBJECT(qbool_from_int(va_arg(*ap, int)));
205
+ } else if (!strcmp(val, "%d")) {
206
+ - obj = QOBJECT(qint_from_int(va_arg(*ap, int)));
207
+ + return QOBJECT(qint_from_int(va_arg(*ap, int)));
208
+ } else if (!strcmp(val, "%ld")) {
209
+ - obj = QOBJECT(qint_from_int(va_arg(*ap, long)));
210
+ + return QOBJECT(qint_from_int(va_arg(*ap, long)));
211
+ } else if (!strcmp(val, "%lld") ||
212
+ !strcmp(val, "%I64d")) {
213
+ - obj = QOBJECT(qint_from_int(va_arg(*ap, long long)));
214
+ + return QOBJECT(qint_from_int(va_arg(*ap, long long)));
215
+ } else if (!strcmp(val, "%s")) {
216
+ - obj = QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
217
+ + return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
218
+ } else if (!strcmp(val, "%f")) {
219
+ - obj = QOBJECT(qfloat_from_double(va_arg(*ap, double)));
220
+ - } else {
221
+ - goto out;
222
+ + return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
223
+ }
224
+ -
225
+ - return obj;
226
+ -
227
+ -out:
228
+ - parser_context_restore(ctxt, saved_ctxt);
229
+ -
230
+ return NULL;
231
+ }
232
+
233
+ static QObject *parse_literal(JSONParserContext *ctxt)
234
+ {
235
+ - QObject *token, *obj;
236
+ - JSONParserContext saved_ctxt = parser_context_save(ctxt);
237
+ + QObject *token;
238
+
239
+ token = parser_context_pop_token(ctxt);
240
+ - if (token == NULL) {
241
+ - goto out;
242
+ - }
243
+ + assert(token);
244
+
245
+ switch (token_get_type(token)) {
246
+ case JSON_STRING:
247
+ - obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
248
+ - break;
249
+ + return QOBJECT(qstring_from_escaped_str(ctxt, token));
250
+ case JSON_INTEGER: {
251
+ /* A possibility exists that this is a whole-valued float where the
252
+ * fractional part was left out due to being 0 (.0). It's not a big
253
+ @@ -626,46 +555,46 @@ static QObject *parse_literal(JSONParserContext *ctxt)
254
+ errno = 0; /* strtoll doesn't set errno on success */
255
+ value = strtoll(token_get_value(token), NULL, 10);
256
+ if (errno != ERANGE) {
257
+ - obj = QOBJECT(qint_from_int(value));
258
+ - break;
259
+ + return QOBJECT(qint_from_int(value));
260
+ }
261
+ /* fall through to JSON_FLOAT */
262
+ }
263
+ case JSON_FLOAT:
264
+ /* FIXME dependent on locale */
265
+ - obj = QOBJECT(qfloat_from_double(strtod(token_get_value(token), NULL)));
266
+ - break;
267
+ + return QOBJECT(qfloat_from_double(strtod(token_get_value(token),
268
+ + NULL)));
269
+ default:
270
+ - goto out;
271
+ + abort();
272
+ }
273
+ -
274
+ - return obj;
275
+ -
276
+ -out:
277
+ - parser_context_restore(ctxt, saved_ctxt);
278
+ -
279
+ - return NULL;
280
+ }
281
+
282
+ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
283
+ {
284
+ - QObject *obj;
285
+ + QObject *token;
286
+
287
+ - obj = parse_object(ctxt, ap);
288
+ - if (obj == NULL) {
289
+ - obj = parse_array(ctxt, ap);
290
+ - }
291
+ - if (obj == NULL) {
292
+ - obj = parse_escape(ctxt, ap);
293
+ - }
294
+ - if (obj == NULL) {
295
+ - obj = parse_keyword(ctxt);
296
+ - }
297
+ - if (obj == NULL) {
298
+ - obj = parse_literal(ctxt);
299
+ + token = parser_context_peek_token(ctxt);
300
+ + if (token == NULL) {
301
+ + parse_error(ctxt, NULL, "premature EOI");
302
+ + return NULL;
303
+ }
304
+
305
+ - return obj;
306
+ + switch (token_get_type(token)) {
307
+ + case JSON_LCURLY:
308
+ + return parse_object(ctxt, ap);
309
+ + case JSON_LSQUARE:
310
+ + return parse_array(ctxt, ap);
311
+ + case JSON_ESCAPE:
312
+ + return parse_escape(ctxt, ap);
313
+ + case JSON_INTEGER:
314
+ + case JSON_FLOAT:
315
+ + case JSON_STRING:
316
+ + return parse_literal(ctxt);
317
+ + case JSON_KEYWORD:
318
+ + return parse_keyword(ctxt);
319
+ + default:
320
+ + parse_error(ctxt, token, "expecting value");
321
+ + return NULL;
322
+ + }
323
+ }
324
+
325
+ QObject *json_parser_parse(QList *tokens, va_list *ap)
326
+ --
327
+ 1.8.3.1
328
+
SOURCES/kvm-qjson-Don-t-crash-when-input-exceeds-nesting-limit.patch ADDED
@@ -0,0 +1,62 @@
1
+ From ba9229d280e035872ac2258873c1b9f34cc8c4a9 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:01 +0200
4
+ Subject: [PATCH 03/16] qjson: Don't crash when input exceeds nesting limit
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-5-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71472
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 03/15] qjson: Don't crash when input exceeds nesting limit
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ We limit nesting depth and input size to defend against input
16
+ triggering excessive heap or stack memory use (commit 29c75dd
17
+ json-streamer: limit the maximum recursion depth and maximum token
18
+ count). However, when the nesting limit is exceeded,
19
+ parser_context_peek_token()'s assertion fails.
20
+
21
+ Broken in commit 65c0f1e "json-parser: don't replicate tokens at each
22
+ level of recursion".
23
+
24
+ To reproduce stuff 1025 open braces or brackets into QMP.
25
+
26
+ Fix by taking the error exit instead of the normal one.
27
+
28
+ Reported-by: Eric Blake <eblake@redhat.com>
29
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
30
+ Reviewed-by: Eric Blake <eblake@redhat.com>
31
+ Message-Id: <1448486613-17634-3-git-send-email-armbru@redhat.com>
32
+ (cherry picked from commit 0753113a26bb8c77f951b1ea91fd4f36d099c37a)
33
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
34
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
35
+ ---
36
+ qobject/json-streamer.c | 5 +++--
37
+ 1 file changed, 3 insertions(+), 2 deletions(-)
38
+
39
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
40
+ index dced2c7..2bd22a7 100644
41
+ --- a/qobject/json-streamer.c
42
+ +++ b/qobject/json-streamer.c
43
+ @@ -68,13 +68,14 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
44
+ /* Security consideration, we limit total memory allocated per object
45
+ * and the maximum recursion depth that a message can force.
46
+ */
47
+ - goto out_emit;
48
+ + goto out_emit_bad;
49
+ }
50
+
51
+ return;
52
+
53
+ out_emit_bad:
54
+ - /* clear out token list and tell the parser to emit and error
55
+ + /*
56
+ + * Clear out token list and tell the parser to emit an error
57
+ * indication by passing it a NULL list
58
+ */
59
+ QDECREF(parser->tokens);
60
+ --
61
+ 1.8.3.1
62
+
SOURCES/kvm-qjson-Give-each-of-the-six-structural-chars-its-own-.patch ADDED
@@ -0,0 +1,222 @@
1
+ From 95aeff93da762bf7f69317eb674d3eccce672038 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:04 +0200
4
+ Subject: [PATCH 06/16] qjson: Give each of the six structural chars its own
5
+ token type
6
+
7
+ RH-Author: Markus Armbruster <armbru@redhat.com>
8
+ Message-id: <1469604913-12442-8-git-send-email-armbru@redhat.com>
9
+ Patchwork-id: 71482
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 06/15] qjson: Give each of the six structural chars its own token type
11
+ Bugzilla: 1276036
12
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
13
+ RH-Acked-by: John Snow <jsnow@redhat.com>
14
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
15
+
16
+ Simplifies things, because we always check for a specific one.
17
+
18
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
19
+ Message-Id: <1448486613-17634-6-git-send-email-armbru@redhat.com>
20
+ Reviewed-by: Eric Blake <eblake@redhat.com>
21
+ (cherry picked from commit c54616608af442edf4cfb7397a1909c2653efba0)
22
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
23
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
24
+ ---
25
+ include/qapi/qmp/json-lexer.h | 7 ++++++-
26
+ qobject/json-lexer.c | 19 ++++++++++++-------
27
+ qobject/json-parser.c | 31 +++++++++----------------------
28
+ qobject/json-streamer.c | 32 +++++++++++++++-----------------
29
+ 4 files changed, 42 insertions(+), 47 deletions(-)
30
+
31
+ diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
32
+ index 61a143f..f3e8dc7 100644
33
+ --- a/include/qapi/qmp/json-lexer.h
34
+ +++ b/include/qapi/qmp/json-lexer.h
35
+ @@ -19,7 +19,12 @@
36
+
37
+ typedef enum json_token_type {
38
+ JSON_MIN = 100,
39
+ - JSON_OPERATOR = JSON_MIN,
40
+ + JSON_LCURLY = JSON_MIN,
41
+ + JSON_RCURLY,
42
+ + JSON_LSQUARE,
43
+ + JSON_RSQUARE,
44
+ + JSON_COLON,
45
+ + JSON_COMMA,
46
+ JSON_INTEGER,
47
+ JSON_FLOAT,
48
+ JSON_KEYWORD,
49
+ diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
50
+ index f106ffb..1bfff02 100644
51
+ --- a/qobject/json-lexer.c
52
+ +++ b/qobject/json-lexer.c
53
+ @@ -257,12 +257,12 @@ static const uint8_t json_lexer[][256] = {
54
+ ['0'] = IN_ZERO,
55
+ ['1' ... '9'] = IN_NONZERO_NUMBER,
56
+ ['-'] = IN_NEG_NONZERO_NUMBER,
57
+ - ['{'] = JSON_OPERATOR,
58
+ - ['}'] = JSON_OPERATOR,
59
+ - ['['] = JSON_OPERATOR,
60
+ - [']'] = JSON_OPERATOR,
61
+ - [','] = JSON_OPERATOR,
62
+ - [':'] = JSON_OPERATOR,
63
+ + ['{'] = JSON_LCURLY,
64
+ + ['}'] = JSON_RCURLY,
65
+ + ['['] = JSON_LSQUARE,
66
+ + [']'] = JSON_RSQUARE,
67
+ + [','] = JSON_COMMA,
68
+ + [':'] = JSON_COLON,
69
+ ['a' ... 'z'] = IN_KEYWORD,
70
+ ['%'] = IN_ESCAPE,
71
+ [' '] = IN_WHITESPACE,
72
+ @@ -299,7 +299,12 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
73
+ }
74
+
75
+ switch (new_state) {
76
+ - case JSON_OPERATOR:
77
+ + case JSON_LCURLY:
78
+ + case JSON_RCURLY:
79
+ + case JSON_LSQUARE:
80
+ + case JSON_RSQUARE:
81
+ + case JSON_COLON:
82
+ + case JSON_COMMA:
83
+ case JSON_ESCAPE:
84
+ case JSON_INTEGER:
85
+ case JSON_FLOAT:
86
+ diff --git a/qobject/json-parser.c b/qobject/json-parser.c
87
+ index fa09769..50bf30c 100644
88
+ --- a/qobject/json-parser.c
89
+ +++ b/qobject/json-parser.c
90
+ @@ -64,19 +64,6 @@ static JSONTokenType token_get_type(QObject *obj)
91
+ return qdict_get_int(qobject_to_qdict(obj), "type");
92
+ }
93
+
94
+ -static int token_is_operator(QObject *obj, char op)
95
+ -{
96
+ - const char *val;
97
+ -
98
+ - if (token_get_type(obj) != JSON_OPERATOR) {
99
+ - return 0;
100
+ - }
101
+ -
102
+ - val = token_get_value(obj);
103
+ -
104
+ - return (val[0] == op) && (val[1] == 0);
105
+ -}
106
+ -
107
+ static int token_is_keyword(QObject *obj, const char *value)
108
+ {
109
+ if (token_get_type(obj) != JSON_KEYWORD) {
110
+ @@ -385,7 +372,7 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
111
+ goto out;
112
+ }
113
+
114
+ - if (!token_is_operator(token, ':')) {
115
+ + if (token_get_type(token) != JSON_COLON) {
116
+ parse_error(ctxt, token, "missing : in object pair");
117
+ goto out;
118
+ }
119
+ @@ -420,7 +407,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
120
+ goto out;
121
+ }
122
+
123
+ - if (!token_is_operator(token, '{')) {
124
+ + if (token_get_type(token) != JSON_LCURLY) {
125
+ goto out;
126
+ }
127
+
128
+ @@ -432,7 +419,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
129
+ goto out;
130
+ }
131
+
132
+ - if (!token_is_operator(peek, '}')) {
133
+ + if (token_get_type(peek) != JSON_RCURLY) {
134
+ if (parse_pair(ctxt, dict, ap) == -1) {
135
+ goto out;
136
+ }
137
+ @@ -443,8 +430,8 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
138
+ goto out;
139
+ }
140
+
141
+ - while (!token_is_operator(token, '}')) {
142
+ - if (!token_is_operator(token, ',')) {
143
+ + while (token_get_type(token) != JSON_RCURLY) {
144
+ + if (token_get_type(token) != JSON_COMMA) {
145
+ parse_error(ctxt, token, "expected separator in dict");
146
+ goto out;
147
+ }
148
+ @@ -482,7 +469,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
149
+ goto out;
150
+ }
151
+
152
+ - if (!token_is_operator(token, '[')) {
153
+ + if (token_get_type(token) != JSON_LSQUARE) {
154
+ goto out;
155
+ }
156
+
157
+ @@ -494,7 +481,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
158
+ goto out;
159
+ }
160
+
161
+ - if (!token_is_operator(peek, ']')) {
162
+ + if (token_get_type(peek) != JSON_RSQUARE) {
163
+ QObject *obj;
164
+
165
+ obj = parse_value(ctxt, ap);
166
+ @@ -511,8 +498,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
167
+ goto out;
168
+ }
169
+
170
+ - while (!token_is_operator(token, ']')) {
171
+ - if (!token_is_operator(token, ',')) {
172
+ + while (token_get_type(token) != JSON_RSQUARE) {
173
+ + if (token_get_type(token) != JSON_COMMA) {
174
+ parse_error(ctxt, token, "expected separator in list");
175
+ goto out;
176
+ }
177
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
178
+ index 2bd22a7..4a161a1 100644
179
+ --- a/qobject/json-streamer.c
180
+ +++ b/qobject/json-streamer.c
181
+ @@ -26,23 +26,21 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
182
+ JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
183
+ QDict *dict;
184
+
185
+ - if (type == JSON_OPERATOR) {
186
+ - switch (qstring_get_str(token)[0]) {
187
+ - case '{':
188
+ - parser->brace_count++;
189
+ - break;
190
+ - case '}':
191
+ - parser->brace_count--;
192
+ - break;
193
+ - case '[':
194
+ - parser->bracket_count++;
195
+ - break;
196
+ - case ']':
197
+ - parser->bracket_count--;
198
+ - break;
199
+ - default:
200
+ - break;
201
+ - }
202
+ + switch (type) {
203
+ + case JSON_LCURLY:
204
+ + parser->brace_count++;
205
+ + break;
206
+ + case JSON_RCURLY:
207
+ + parser->brace_count--;
208
+ + break;
209
+ + case JSON_LSQUARE:
210
+ + parser->bracket_count++;
211
+ + break;
212
+ + case JSON_RSQUARE:
213
+ + parser->bracket_count--;
214
+ + break;
215
+ + default:
216
+ + break;
217
+ }
218
+
219
+ dict = qdict_new();
220
+ --
221
+ 1.8.3.1
222
+
SOURCES/kvm-qjson-Inline-token_is_escape-and-simplify.patch ADDED
@@ -0,0 +1,97 @@
1
+ From 225cb3d48dd4dcbc7bf845c0b4b06a90030874f3 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:06 +0200
4
+ Subject: [PATCH 08/16] qjson: Inline token_is_escape() and simplify
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-10-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71479
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 08/15] qjson: Inline token_is_escape() and simplify
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
16
+ Message-Id: <1448486613-17634-8-git-send-email-armbru@redhat.com>
17
+ Reviewed-by: Eric Blake <eblake@redhat.com>
18
+ (cherry picked from commit 6b9606f68ec589def27bd2a9cea97ec63cffd581)
19
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
20
+
21
+ Conflicts:
22
+ qobject/json-parser.c
23
+
24
+ Straighforward conflict because lacking commit fc48ffc "qobject: Use
25
+ 'bool' for qbool", we still use qbool_from_int().
26
+
27
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
28
+ ---
29
+ qobject/json-parser.c | 32 +++++++++++++++-----------------
30
+ 1 file changed, 15 insertions(+), 17 deletions(-)
31
+
32
+ diff --git a/qobject/json-parser.c b/qobject/json-parser.c
33
+ index e3690de..79f4173 100644
34
+ --- a/qobject/json-parser.c
35
+ +++ b/qobject/json-parser.c
36
+ @@ -64,15 +64,6 @@ static JSONTokenType token_get_type(QObject *obj)
37
+ return qdict_get_int(qobject_to_qdict(obj), "type");
38
+ }
39
+
40
+ -static int token_is_escape(QObject *obj, const char *value)
41
+ -{
42
+ - if (token_get_type(obj) != JSON_ESCAPE) {
43
+ - return 0;
44
+ - }
45
+ -
46
+ - return (strcmp(token_get_value(obj), value) == 0);
47
+ -}
48
+ -
49
+ /**
50
+ * Error handler
51
+ */
52
+ @@ -559,6 +550,7 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
53
+ {
54
+ QObject *token = NULL, *obj;
55
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
56
+ + const char *val;
57
+
58
+ if (ap == NULL) {
59
+ goto out;
60
+ @@ -569,20 +561,26 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
61
+ goto out;
62
+ }
63
+
64
+ - if (token_is_escape(token, "%p")) {
65
+ + if (token_get_type(token) != JSON_ESCAPE) {
66
+ + goto out;
67
+ + }
68
+ +
69
+ + val = token_get_value(token);
70
+ +
71
+ + if (!strcmp(val, "%p")) {
72
+ obj = va_arg(*ap, QObject *);
73
+ - } else if (token_is_escape(token, "%i")) {
74
+ + } else if (!strcmp(val, "%i")) {
75
+ obj = QOBJECT(qbool_from_int(va_arg(*ap, int)));
76
+ - } else if (token_is_escape(token, "%d")) {
77
+ + } else if (!strcmp(val, "%d")) {
78
+ obj = QOBJECT(qint_from_int(va_arg(*ap, int)));
79
+ - } else if (token_is_escape(token, "%ld")) {
80
+ + } else if (!strcmp(val, "%ld")) {
81
+ obj = QOBJECT(qint_from_int(va_arg(*ap, long)));
82
+ - } else if (token_is_escape(token, "%lld") ||
83
+ - token_is_escape(token, "%I64d")) {
84
+ + } else if (!strcmp(val, "%lld") ||
85
+ + !strcmp(val, "%I64d")) {
86
+ obj = QOBJECT(qint_from_int(va_arg(*ap, long long)));
87
+ - } else if (token_is_escape(token, "%s")) {
88
+ + } else if (!strcmp(val, "%s")) {
89
+ obj = QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
90
+ - } else if (token_is_escape(token, "%f")) {
91
+ + } else if (!strcmp(val, "%f")) {
92
+ obj = QOBJECT(qfloat_from_double(va_arg(*ap, double)));
93
+ } else {
94
+ goto out;
95
+ --
96
+ 1.8.3.1
97
+
SOURCES/kvm-qjson-Inline-token_is_keyword-and-simplify.patch ADDED
@@ -0,0 +1,81 @@
1
+ From 3cf8ec8ff0ad3920ce23166b2576655bcd886c5a Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:05 +0200
4
+ Subject: [PATCH 07/16] qjson: Inline token_is_keyword() and simplify
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-9-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71483
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 07/15] qjson: Inline token_is_keyword() and simplify
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
16
+ Message-Id: <1448486613-17634-7-git-send-email-armbru@redhat.com>
17
+ Reviewed-by: Eric Blake <eblake@redhat.com>
18
+ (cherry picked from commit 50e2a467f5315fa36c547fb6330659ba45f6bb83)
19
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
20
+
21
+ Conflicts:
22
+ qobject/json-parser.c
23
+
24
+ Straighforward conflict because lacking commit fc48ffc "qobject: Use
25
+ 'bool' for qbool", we still use qbool_from_int(), and we lack commit
26
+ e549e71 "json-parser: Accept 'null' in QMP".
27
+
28
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
29
+ ---
30
+ qobject/json-parser.c | 18 ++++++------------
31
+ 1 file changed, 6 insertions(+), 12 deletions(-)
32
+
33
+ diff --git a/qobject/json-parser.c b/qobject/json-parser.c
34
+ index 50bf30c..e3690de 100644
35
+ --- a/qobject/json-parser.c
36
+ +++ b/qobject/json-parser.c
37
+ @@ -64,15 +64,6 @@ static JSONTokenType token_get_type(QObject *obj)
38
+ return qdict_get_int(qobject_to_qdict(obj), "type");
39
+ }
40
+
41
+ -static int token_is_keyword(QObject *obj, const char *value)
42
+ -{
43
+ - if (token_get_type(obj) != JSON_KEYWORD) {
44
+ - return 0;
45
+ - }
46
+ -
47
+ - return strcmp(token_get_value(obj), value) == 0;
48
+ -}
49
+ -
50
+ static int token_is_escape(QObject *obj, const char *value)
51
+ {
52
+ if (token_get_type(obj) != JSON_ESCAPE) {
53
+ @@ -534,6 +525,7 @@ static QObject *parse_keyword(JSONParserContext *ctxt)
54
+ {
55
+ QObject *token, *ret;
56
+ JSONParserContext saved_ctxt = parser_context_save(ctxt);
57
+ + const char *val;
58
+
59
+ token = parser_context_pop_token(ctxt);
60
+ if (token == NULL) {
61
+ @@ -544,12 +536,14 @@ static QObject *parse_keyword(JSONParserContext *ctxt)
62
+ goto out;
63
+ }
64
+
65
+ - if (token_is_keyword(token, "true")) {
66
+ + val = token_get_value(token);
67
+ +
68
+ + if (!strcmp(val, "true")) {
69
+ ret = QOBJECT(qbool_from_int(true));
70
+ - } else if (token_is_keyword(token, "false")) {
71
+ + } else if (!strcmp(val, "false")) {
72
+ ret = QOBJECT(qbool_from_int(false));
73
+ } else {
74
+ - parse_error(ctxt, token, "invalid keyword `%s'", token_get_value(token));
75
+ + parse_error(ctxt, token, "invalid keyword '%s'", val);
76
+ goto out;
77
+ }
78
+
79
+ --
80
+ 1.8.3.1
81
+
SOURCES/kvm-qjson-Limit-number-of-tokens-in-addition-to-total-si.patch ADDED
@@ -0,0 +1,59 @@
1
+ From 60ad1bad25ea99c538b745ff95e6e0a877d37d1f Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:11 +0200
4
+ Subject: [PATCH 13/16] qjson: Limit number of tokens in addition to total size
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-15-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71476
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 13/15] qjson: Limit number of tokens in addition to total size
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ Commit 29c75dd "json-streamer: limit the maximum recursion depth and
16
+ maximum token count" attempts to guard against excessive heap usage by
17
+ limiting total token size (it says "token count", but that's a lie).
18
+
19
+ Total token size is a rather imprecise predictor of heap usage: many
20
+ small tokens use more space than few large tokens with the same input
21
+ size, because there's a constant per-token overhead: 37 bytes on my
22
+ system.
23
+
24
+ Tighten this up: limit the token count to 2Mi. Chosen to roughly
25
+ match the 64MiB total token size limit.
26
+
27
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
28
+ Reviewed-by: Eric Blake <eblake@redhat.com>
29
+ Message-Id: <1448486613-17634-13-git-send-email-armbru@redhat.com>
30
+ (cherry picked from commit df649835fe48f635a93316fdefe96ced7189316e)
31
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
32
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
33
+ ---
34
+ qobject/json-streamer.c | 2 ++
35
+ 1 file changed, 2 insertions(+)
36
+
37
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
38
+ index e87230d..a4db4b8 100644
39
+ --- a/qobject/json-streamer.c
40
+ +++ b/qobject/json-streamer.c
41
+ @@ -16,6 +16,7 @@
42
+ #include "qapi/qmp/json-streamer.h"
43
+
44
+ #define MAX_TOKEN_SIZE (64ULL << 20)
45
+ +#define MAX_TOKEN_COUNT (2ULL << 20)
46
+ #define MAX_NESTING (1ULL << 10)
47
+
48
+ static void json_message_free_tokens(JSONMessageParser *parser)
49
+ @@ -68,6 +69,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
50
+ parser->bracket_count == 0)) {
51
+ goto out_emit;
52
+ } else if (parser->token_size > MAX_TOKEN_SIZE ||
53
+ + g_queue_get_length(parser->tokens) > MAX_TOKEN_COUNT ||
54
+ parser->bracket_count + parser->brace_count > MAX_NESTING) {
55
+ /* Security consideration, we limit total memory allocated per object
56
+ * and the maximum recursion depth that a message can force.
57
+ --
58
+ 1.8.3.1
59
+
SOURCES/kvm-qjson-Spell-out-some-silent-assumptions.patch ADDED
@@ -0,0 +1,81 @@
1
+ From c4c2e01b3fa861de40f809785a0643d56e2b311e Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:03 +0200
4
+ Subject: [PATCH 05/16] qjson: Spell out some silent assumptions
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-7-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71473
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 05/15] qjson: Spell out some silent assumptions
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
16
+ Message-Id: <1448486613-17634-5-git-send-email-armbru@redhat.com>
17
+ Reviewed-by: Eric Blake <eblake@redhat.com>
18
+ (cherry picked from commit b8d3b1da3cdbb02e180618d6be346c564723015d)
19
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
20
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
21
+ ---
22
+ include/qapi/qmp/json-lexer.h | 3 ++-
23
+ qobject/json-lexer.c | 7 ++++++-
24
+ 2 files changed, 8 insertions(+), 2 deletions(-)
25
+
26
+ diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
27
+ index cdff046..61a143f 100644
28
+ --- a/include/qapi/qmp/json-lexer.h
29
+ +++ b/include/qapi/qmp/json-lexer.h
30
+ @@ -18,7 +18,8 @@
31
+ #include "qapi/qmp/qlist.h"
32
+
33
+ typedef enum json_token_type {
34
+ - JSON_OPERATOR = 100,
35
+ + JSON_MIN = 100,
36
+ + JSON_OPERATOR = JSON_MIN,
37
+ JSON_INTEGER,
38
+ JSON_FLOAT,
39
+ JSON_KEYWORD,
40
+ diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
41
+ index 440df60..f106ffb 100644
42
+ --- a/qobject/json-lexer.c
43
+ +++ b/qobject/json-lexer.c
44
+ @@ -30,7 +30,7 @@
45
+ */
46
+
47
+ enum json_lexer_state {
48
+ - IN_ERROR = 0,
49
+ + IN_ERROR = 0, /* must really be 0, see json_lexer[] */
50
+ IN_DQ_UCODE3,
51
+ IN_DQ_UCODE2,
52
+ IN_DQ_UCODE1,
53
+ @@ -62,6 +62,8 @@ enum json_lexer_state {
54
+ IN_START,
55
+ };
56
+
57
+ +QEMU_BUILD_BUG_ON((int)JSON_MIN <= (int)IN_START);
58
+ +
59
+ #define TERMINAL(state) [0 ... 0x7F] = (state)
60
+
61
+ /* Return whether TERMINAL is a terminal state and the transition to it
62
+ @@ -71,6 +73,8 @@ enum json_lexer_state {
63
+ (json_lexer[(old_state)][0] == (terminal))
64
+
65
+ static const uint8_t json_lexer[][256] = {
66
+ + /* Relies on default initialization to IN_ERROR! */
67
+ +
68
+ /* double quote string */
69
+ [IN_DQ_UCODE3] = {
70
+ ['0' ... '9'] = IN_DQ_STRING,
71
+ @@ -287,6 +291,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
72
+ }
73
+
74
+ do {
75
+ + assert(lexer->state <= ARRAY_SIZE(json_lexer));
76
+ new_state = json_lexer[lexer->state][(uint8_t)ch];
77
+ char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state);
78
+ if (char_consumed) {
79
+ --
80
+ 1.8.3.1
81
+
SOURCES/kvm-qjson-replace-QString-in-JSONLexer-with-GString.patch ADDED
@@ -0,0 +1,195 @@
1
+ From 39da81cf143ccc400263362a5319803063ad14cf Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:07 +0200
4
+ Subject: [PATCH 09/16] qjson: replace QString in JSONLexer with GString
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-11-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71480
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 09/15] qjson: replace QString in JSONLexer with GString
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Paolo Bonzini <pbonzini@redhat.com>
16
+
17
+ JSONLexer only needs a simple resizable buffer. json-streamer.c
18
+ can allocate memory for each token instead of relying on reference
19
+ counting of QStrings.
20
+
21
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
22
+ Message-Id: <1448300659-23559-2-git-send-email-pbonzini@redhat.com>
23
+ [Straightforwardly rebased on my patches, checkpatch made happy]
24
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
25
+ Reviewed-by: Eric Blake <eblake@redhat.com>
26
+ (cherry picked from commit d2ca7c0b0d876cf0e219ae7a92252626b0913a28)
27
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
28
+
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ include/qapi/qmp/json-lexer.h | 8 ++++----
32
+ include/qapi/qmp/json-streamer.h | 1 +
33
+ qobject/json-lexer.c | 22 ++++++++--------------
34
+ qobject/json-streamer.c | 9 +++++----
35
+ 4 files changed, 18 insertions(+), 22 deletions(-)
36
+
37
+ diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
38
+ index f3e8dc7..cb456d5 100644
39
+ --- a/include/qapi/qmp/json-lexer.h
40
+ +++ b/include/qapi/qmp/json-lexer.h
41
+ @@ -14,8 +14,7 @@
42
+ #ifndef QEMU_JSON_LEXER_H
43
+ #define QEMU_JSON_LEXER_H
44
+
45
+ -#include "qapi/qmp/qstring.h"
46
+ -#include "qapi/qmp/qlist.h"
47
+ +#include "glib-compat.h"
48
+
49
+ typedef enum json_token_type {
50
+ JSON_MIN = 100,
51
+ @@ -36,13 +35,14 @@ typedef enum json_token_type {
52
+
53
+ typedef struct JSONLexer JSONLexer;
54
+
55
+ -typedef void (JSONLexerEmitter)(JSONLexer *, QString *, JSONTokenType, int x, int y);
56
+ +typedef void (JSONLexerEmitter)(JSONLexer *, GString *,
57
+ + JSONTokenType, int x, int y);
58
+
59
+ struct JSONLexer
60
+ {
61
+ JSONLexerEmitter *emit;
62
+ int state;
63
+ - QString *token;
64
+ + GString *token;
65
+ int x, y;
66
+ };
67
+
68
+ diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
69
+ index 823f7d7..e901144 100644
70
+ --- a/include/qapi/qmp/json-streamer.h
71
+ +++ b/include/qapi/qmp/json-streamer.h
72
+ @@ -14,6 +14,7 @@
73
+ #ifndef QEMU_JSON_STREAMER_H
74
+ #define QEMU_JSON_STREAMER_H
75
+
76
+ +#include <stdint.h>
77
+ #include "qapi/qmp/qlist.h"
78
+ #include "qapi/qmp/json-lexer.h"
79
+
80
+ diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
81
+ index 1bfff02..b89e24f 100644
82
+ --- a/qobject/json-lexer.c
83
+ +++ b/qobject/json-lexer.c
84
+ @@ -11,12 +11,9 @@
85
+ *
86
+ */
87
+
88
+ -#include "qapi/qmp/qstring.h"
89
+ -#include "qapi/qmp/qlist.h"
90
+ -#include "qapi/qmp/qdict.h"
91
+ -#include "qapi/qmp/qint.h"
92
+ #include "qemu-common.h"
93
+ #include "qapi/qmp/json-lexer.h"
94
+ +#include <stdint.h>
95
+
96
+ #define MAX_TOKEN_SIZE (64ULL << 20)
97
+
98
+ @@ -276,7 +273,7 @@ void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
99
+ {
100
+ lexer->emit = func;
101
+ lexer->state = IN_START;
102
+ - lexer->token = qstring_new();
103
+ + lexer->token = g_string_sized_new(3);
104
+ lexer->x = lexer->y = 0;
105
+ }
106
+
107
+ @@ -295,7 +292,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
108
+ new_state = json_lexer[lexer->state][(uint8_t)ch];
109
+ char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state);
110
+ if (char_consumed) {
111
+ - qstring_append_chr(lexer->token, ch);
112
+ + g_string_append_c(lexer->token, ch);
113
+ }
114
+
115
+ switch (new_state) {
116
+ @@ -313,8 +310,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
117
+ lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y);
118
+ /* fall through */
119
+ case JSON_SKIP:
120
+ - QDECREF(lexer->token);
121
+ - lexer->token = qstring_new();
122
+ + g_string_truncate(lexer->token, 0);
123
+ new_state = IN_START;
124
+ break;
125
+ case IN_ERROR:
126
+ @@ -332,8 +328,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
127
+ * induce an error/flush state.
128
+ */
129
+ lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y);
130
+ - QDECREF(lexer->token);
131
+ - lexer->token = qstring_new();
132
+ + g_string_truncate(lexer->token, 0);
133
+ new_state = IN_START;
134
+ lexer->state = new_state;
135
+ return 0;
136
+ @@ -346,10 +341,9 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
137
+ /* Do not let a single token grow to an arbitrarily large size,
138
+ * this is a security consideration.
139
+ */
140
+ - if (lexer->token->length > MAX_TOKEN_SIZE) {
141
+ + if (lexer->token->len > MAX_TOKEN_SIZE) {
142
+ lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y);
143
+ - QDECREF(lexer->token);
144
+ - lexer->token = qstring_new();
145
+ + g_string_truncate(lexer->token, 0);
146
+ lexer->state = IN_START;
147
+ }
148
+
149
+ @@ -379,5 +373,5 @@ int json_lexer_flush(JSONLexer *lexer)
150
+
151
+ void json_lexer_destroy(JSONLexer *lexer)
152
+ {
153
+ - QDECREF(lexer->token);
154
+ + g_string_free(lexer->token, true);
155
+ }
156
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
157
+ index 4a161a1..7292f3a 100644
158
+ --- a/qobject/json-streamer.c
159
+ +++ b/qobject/json-streamer.c
160
+ @@ -12,6 +12,7 @@
161
+ */
162
+
163
+ #include "qapi/qmp/qlist.h"
164
+ +#include "qapi/qmp/qstring.h"
165
+ #include "qapi/qmp/qint.h"
166
+ #include "qapi/qmp/qdict.h"
167
+ #include "qemu-common.h"
168
+ @@ -21,7 +22,8 @@
169
+ #define MAX_TOKEN_SIZE (64ULL << 20)
170
+ #define MAX_NESTING (1ULL << 10)
171
+
172
+ -static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
173
+ +static void json_message_process_token(JSONLexer *lexer, GString *input,
174
+ + JSONTokenType type, int x, int y)
175
+ {
176
+ JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
177
+ QDict *dict;
178
+ @@ -45,12 +47,11 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
179
+
180
+ dict = qdict_new();
181
+ qdict_put(dict, "type", qint_from_int(type));
182
+ - QINCREF(token);
183
+ - qdict_put(dict, "token", token);
184
+ + qdict_put(dict, "token", qstring_from_str(input->str));
185
+ qdict_put(dict, "x", qint_from_int(x));
186
+ qdict_put(dict, "y", qint_from_int(y));
187
+
188
+ - parser->token_size += token->length;
189
+ + parser->token_size += input->len;
190
+
191
+ qlist_append(parser->tokens, dict);
192
+
193
+ --
194
+ 1.8.3.1
195
+
SOURCES/kvm-qjson-store-tokens-in-a-GQueue.patch ADDED
@@ -0,0 +1,332 @@
1
+ From 88ee76fed6344de6cede3bfbb3873423e9a90333 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:09 +0200
4
+ Subject: [PATCH 11/16] qjson: store tokens in a GQueue
5
+
6
+ RH-Author: Markus Armbruster <armbru@redhat.com>
7
+ Message-id: <1469604913-12442-13-git-send-email-armbru@redhat.com>
8
+ Patchwork-id: 71478
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 11/15] qjson: store tokens in a GQueue
10
+ Bugzilla: 1276036
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Paolo Bonzini <pbonzini@redhat.com>
16
+
17
+ Even though we still have the "streamer" concept, the tokens can now
18
+ be deleted as they are read. While doing so convert from QList to
19
+ GQueue, since the next step will make tokens not a QObject and we
20
+ will have to do the conversion anyway.
21
+
22
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
23
+ Message-Id: <1448300659-23559-4-git-send-email-pbonzini@redhat.com>
24
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
25
+ Reviewed-by: Eric Blake <eblake@redhat.com>
26
+ (cherry picked from commit 95385fe9ace7db156b924da6b6f5c9082b68ba68)
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+
29
+ Conflicts:
30
+ monitor.c
31
+
32
+ Trivial context difference because we lack a small cleanup part of the
33
+ (fairly invasive) series b821cbe..489653b.
34
+
35
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
36
+ ---
37
+ include/qapi/qmp/json-parser.h | 4 +--
38
+ include/qapi/qmp/json-streamer.h | 8 ++---
39
+ monitor.c | 2 +-
40
+ qga/main.c | 2 +-
41
+ qobject/json-parser.c | 65 +++++++++++++---------------------------
42
+ qobject/json-streamer.c | 25 +++++++++-------
43
+ qobject/qjson.c | 2 +-
44
+ tests/libqtest.c | 2 +-
45
+ 8 files changed, 45 insertions(+), 65 deletions(-)
46
+
47
+ diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h
48
+ index 44d88f3..fea89f8 100644
49
+ --- a/include/qapi/qmp/json-parser.h
50
+ +++ b/include/qapi/qmp/json-parser.h
51
+ @@ -18,7 +18,7 @@
52
+ #include "qapi/qmp/qlist.h"
53
+ #include "qapi/error.h"
54
+
55
+ -QObject *json_parser_parse(QList *tokens, va_list *ap);
56
+ -QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp);
57
+ +QObject *json_parser_parse(GQueue *tokens, va_list *ap);
58
+ +QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp);
59
+
60
+ #endif
61
+ diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
62
+ index e901144..e9f2937 100644
63
+ --- a/include/qapi/qmp/json-streamer.h
64
+ +++ b/include/qapi/qmp/json-streamer.h
65
+ @@ -15,21 +15,21 @@
66
+ #define QEMU_JSON_STREAMER_H
67
+
68
+ #include <stdint.h>
69
+ -#include "qapi/qmp/qlist.h"
70
+ +#include "glib-compat.h"
71
+ #include "qapi/qmp/json-lexer.h"
72
+
73
+ typedef struct JSONMessageParser
74
+ {
75
+ - void (*emit)(struct JSONMessageParser *parser, QList *tokens);
76
+ + void (*emit)(struct JSONMessageParser *parser, GQueue *tokens);
77
+ JSONLexer lexer;
78
+ int brace_count;
79
+ int bracket_count;
80
+ - QList *tokens;
81
+ + GQueue *tokens;
82
+ uint64_t token_size;
83
+ } JSONMessageParser;
84
+
85
+ void json_message_parser_init(JSONMessageParser *parser,
86
+ - void (*func)(JSONMessageParser *, QList *));
87
+ + void (*func)(JSONMessageParser *, GQueue *));
88
+
89
+ int json_message_parser_feed(JSONMessageParser *parser,
90
+ const char *buffer, size_t size);
91
+ diff --git a/monitor.c b/monitor.c
92
+ index 33c5bc8..1b28ff3 100644
93
+ --- a/monitor.c
94
+ +++ b/monitor.c
95
+ @@ -4514,7 +4514,7 @@ static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd,
96
+ qobject_decref(data);
97
+ }
98
+
99
+ -static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
100
+ +static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
101
+ {
102
+ int err;
103
+ QObject *obj;
104
+ diff --git a/qga/main.c b/qga/main.c
105
+ index 0e04e73..7e8f9a0 100644
106
+ --- a/qga/main.c
107
+ +++ b/qga/main.c
108
+ @@ -569,7 +569,7 @@ static void process_command(GAState *s, QDict *req)
109
+ }
110
+
111
+ /* handle requests/control events coming in over the channel */
112
+ -static void process_event(JSONMessageParser *parser, QList *tokens)
113
+ +static void process_event(JSONMessageParser *parser, GQueue *tokens)
114
+ {
115
+ GAState *s = container_of(parser, GAState, parser);
116
+ QObject *obj;
117
+ diff --git a/qobject/json-parser.c b/qobject/json-parser.c
118
+ index b242fba..6e5e257 100644
119
+ --- a/qobject/json-parser.c
120
+ +++ b/qobject/json-parser.c
121
+ @@ -27,11 +27,8 @@
122
+ typedef struct JSONParserContext
123
+ {
124
+ Error *err;
125
+ - struct {
126
+ - QObject **buf;
127
+ - size_t pos;
128
+ - size_t count;
129
+ - } tokens;
130
+ + QObject *current;
131
+ + GQueue *buf;
132
+ } JSONParserContext;
133
+
134
+ #define BUG_ON(cond) assert(!(cond))
135
+ @@ -244,56 +241,34 @@ out:
136
+ return NULL;
137
+ }
138
+
139
+ +/* Note: unless the token object returned by parser_context_peek_token
140
+ + * or parser_context_pop_token is explicitly incref'd, it will be
141
+ + * deleted as soon as parser_context_pop_token is called again.
142
+ + */
143
+ static QObject *parser_context_pop_token(JSONParserContext *ctxt)
144
+ {
145
+ - QObject *token;
146
+ - g_assert(ctxt->tokens.pos < ctxt->tokens.count);
147
+ - token = ctxt->tokens.buf[ctxt->tokens.pos];
148
+ - ctxt->tokens.pos++;
149
+ - return token;
150
+ + qobject_decref(ctxt->current);
151
+ + assert(!g_queue_is_empty(ctxt->buf));
152
+ + ctxt->current = g_queue_pop_head(ctxt->buf);
153
+ + return ctxt->current;
154
+ }
155
+
156
+ -/* Note: parser_context_{peek|pop}_token do not increment the
157
+ - * token object's refcount. In both cases the references will continue
158
+ - * to be tracked and cleaned up in parser_context_free(), so do not
159
+ - * attempt to free the token object.
160
+ - */
161
+ static QObject *parser_context_peek_token(JSONParserContext *ctxt)
162
+ {
163
+ - QObject *token;
164
+ - g_assert(ctxt->tokens.pos < ctxt->tokens.count);
165
+ - token = ctxt->tokens.buf[ctxt->tokens.pos];
166
+ - return token;
167
+ -}
168
+ -
169
+ -static void tokens_append_from_iter(QObject *obj, void *opaque)
170
+ -{
171
+ - JSONParserContext *ctxt = opaque;
172
+ - g_assert(ctxt->tokens.pos < ctxt->tokens.count);
173
+ - ctxt->tokens.buf[ctxt->tokens.pos++] = obj;
174
+ - qobject_incref(obj);
175
+ + assert(!g_queue_is_empty(ctxt->buf));
176
+ + return g_queue_peek_head(ctxt->buf);
177
+ }
178
+
179
+ -static JSONParserContext *parser_context_new(QList *tokens)
180
+ +static JSONParserContext *parser_context_new(GQueue *tokens)
181
+ {
182
+ JSONParserContext *ctxt;
183
+ - size_t count;
184
+
185
+ if (!tokens) {
186
+ return NULL;
187
+ }
188
+
189
+ - count = qlist_size(tokens);
190
+ - if (count == 0) {
191
+ - return NULL;
192
+ - }
193
+ -
194
+ ctxt = g_malloc0(sizeof(JSONParserContext));
195
+ - ctxt->tokens.pos = 0;
196
+ - ctxt->tokens.count = count;
197
+ - ctxt->tokens.buf = g_malloc(count * sizeof(QObject *));
198
+ - qlist_iter(tokens, tokens_append_from_iter, ctxt);
199
+ - ctxt->tokens.pos = 0;
200
+ + ctxt->buf = tokens;
201
+
202
+ return ctxt;
203
+ }
204
+ @@ -301,12 +276,12 @@ static JSONParserContext *parser_context_new(QList *tokens)
205
+ /* to support error propagation, ctxt->err must be freed separately */
206
+ static void parser_context_free(JSONParserContext *ctxt)
207
+ {
208
+ - int i;
209
+ if (ctxt) {
210
+ - for (i = 0; i < ctxt->tokens.count; i++) {
211
+ - qobject_decref(ctxt->tokens.buf[i]);
212
+ + while (!g_queue_is_empty(ctxt->buf)) {
213
+ + parser_context_pop_token(ctxt);
214
+ }
215
+ - g_free(ctxt->tokens.buf);
216
+ + qobject_decref(ctxt->current);
217
+ + g_queue_free(ctxt->buf);
218
+ g_free(ctxt);
219
+ }
220
+ }
221
+ @@ -597,12 +572,12 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
222
+ }
223
+ }
224
+
225
+ -QObject *json_parser_parse(QList *tokens, va_list *ap)
226
+ +QObject *json_parser_parse(GQueue *tokens, va_list *ap)
227
+ {
228
+ return json_parser_parse_err(tokens, ap, NULL);
229
+ }
230
+
231
+ -QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp)
232
+ +QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp)
233
+ {
234
+ JSONParserContext *ctxt = parser_context_new(tokens);
235
+ QObject *result;
236
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
237
+ index 7292f3a..f7a3e78 100644
238
+ --- a/qobject/json-streamer.c
239
+ +++ b/qobject/json-streamer.c
240
+ @@ -22,6 +22,14 @@
241
+ #define MAX_TOKEN_SIZE (64ULL << 20)
242
+ #define MAX_NESTING (1ULL << 10)
243
+
244
+ +static void json_message_free_tokens(JSONMessageParser *parser)
245
+ +{
246
+ + if (parser->tokens) {
247
+ + g_queue_free(parser->tokens);
248
+ + parser->tokens = NULL;
249
+ + }
250
+ +}
251
+ +
252
+ static void json_message_process_token(JSONLexer *lexer, GString *input,
253
+ JSONTokenType type, int x, int y)
254
+ {
255
+ @@ -53,7 +61,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
256
+
257
+ parser->token_size += input->len;
258
+
259
+ - qlist_append(parser->tokens, dict);
260
+ + g_queue_push_tail(parser->tokens, dict);
261
+
262
+ if (type == JSON_ERROR) {
263
+ goto out_emit_bad;
264
+ @@ -77,27 +85,24 @@ out_emit_bad:
265
+ * Clear out token list and tell the parser to emit an error
266
+ * indication by passing it a NULL list
267
+ */
268
+ - QDECREF(parser->tokens);
269
+ - parser->tokens = NULL;
270
+ + json_message_free_tokens(parser);
271
+ out_emit:
272
+ /* send current list of tokens to parser and reset tokenizer */
273
+ parser->brace_count = 0;
274
+ parser->bracket_count = 0;
275
+ + /* parser->emit takes ownership of parser->tokens. */
276
+ parser->emit(parser, parser->tokens);
277
+ - if (parser->tokens) {
278
+ - QDECREF(parser->tokens);
279
+ - }
280
+ - parser->tokens = qlist_new();
281
+ + parser->tokens = g_queue_new();
282
+ parser->token_size = 0;
283
+ }
284
+
285
+ void json_message_parser_init(JSONMessageParser *parser,
286
+ - void (*func)(JSONMessageParser *, QList *))
287
+ + void (*func)(JSONMessageParser *, GQueue *))
288
+ {
289
+ parser->emit = func;
290
+ parser->brace_count = 0;
291
+ parser->bracket_count = 0;
292
+ - parser->tokens = qlist_new();
293
+ + parser->tokens = g_queue_new();
294
+ parser->token_size = 0;
295
+
296
+ json_lexer_init(&parser->lexer, json_message_process_token);
297
+ @@ -117,5 +122,5 @@ int json_message_parser_flush(JSONMessageParser *parser)
298
+ void json_message_parser_destroy(JSONMessageParser *parser)
299
+ {
300
+ json_lexer_destroy(&parser->lexer);
301
+ - QDECREF(parser->tokens);
302
+ + json_message_free_tokens(parser);
303
+ }
304
+ diff --git a/qobject/qjson.c b/qobject/qjson.c
305
+ index 6cf2511..fdc274a 100644
306
+ --- a/qobject/qjson.c
307
+ +++ b/qobject/qjson.c
308
+ @@ -28,7 +28,7 @@ typedef struct JSONParsingState
309
+ QObject *result;
310
+ } JSONParsingState;
311
+
312
+ -static void parse_json(JSONMessageParser *parser, QList *tokens)
313
+ +static void parse_json(JSONMessageParser *parser, GQueue *tokens)
314
+ {
315
+ JSONParsingState *s = container_of(parser, JSONParsingState, parser);
316
+ s->result = json_parser_parse(tokens, s->ap);
317
+ diff --git a/tests/libqtest.c b/tests/libqtest.c
318
+ index 359d571..69b7cd6 100644
319
+ --- a/tests/libqtest.c
320
+ +++ b/tests/libqtest.c
321
+ @@ -299,7 +299,7 @@ typedef struct {
322
+ QDict *response;
323
+ } QMPResponseParser;
324
+
325
+ -static void qmp_response(JSONMessageParser *parser, QList *tokens)
326
+ +static void qmp_response(JSONMessageParser *parser, GQueue *tokens)
327
+ {
328
+ QMPResponseParser *qmp = container_of(parser, QMPResponseParser, parser);
329
+ QObject *obj;
330
+ --
331
+ 1.8.3.1
332
+
SOURCES/kvm-qjson-surprise-allocating-6-QObjects-per-token-is-ex.patch ADDED
@@ -0,0 +1,412 @@
1
+ From 7bef5fab7d59aa9a6a1eb6ea747ba04811bc01e2 Mon Sep 17 00:00:00 2001
2
+ From: Markus Armbruster <armbru@redhat.com>
3
+ Date: Wed, 27 Jul 2016 07:35:10 +0200
4
+ Subject: [PATCH 12/16] qjson: surprise, allocating 6 QObjects per token is
5
+ expensive
6
+
7
+ RH-Author: Markus Armbruster <armbru@redhat.com>
8
+ Message-id: <1469604913-12442-14-git-send-email-armbru@redhat.com>
9
+ Patchwork-id: 71475
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 12/15] qjson: surprise, allocating 6 QObjects per token is expensive
11
+ Bugzilla: 1276036
12
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
13
+ RH-Acked-by: John Snow <jsnow@redhat.com>
14
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
15
+
16
+ From: Paolo Bonzini <pbonzini@redhat.com>
17
+
18
+ Replace the contents of the tokens GQueue with a simple struct. This cuts
19
+ the amount of memory allocated by tests/check-qjson from ~500MB to ~20MB,
20
+ and the execution time from 600ms to 80ms on my laptop. Still a lot (some
21
+ could be saved by using an intrusive list, such as QSIMPLEQ, instead of
22
+ the GQueue), but the savings are already massive and the right thing to
23
+ do would probably be to get rid of json-streamer completely.
24
+
25
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
26
+ Message-Id: <1448300659-23559-5-git-send-email-pbonzini@redhat.com>
27
+ [Straightforwardly rebased on my patches]
28
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
29
+ Reviewed-by: Eric Blake <eblake@redhat.com>
30
+ (cherry picked from commit 9bada8971173345ceb37ed1a47b00a01a4dd48cf)
31
+
32
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
33
+
34
+ Conflicts:
35
+ qobject/json-parser.c
36
+
37
+ Straighforward conflicts because lacking commit fc48ffc "qobject: Use
38
+ 'bool' for qbool", we still use qbool_from_int(), and we lack commit
39
+ e549e71 "json-parser: Accept 'null' in QMP".
40
+
41
+ Signed-off-by: Markus Armbruster <armbru@redhat.com>
42
+ ---
43
+ include/qapi/qmp/json-streamer.h | 7 +++
44
+ qobject/json-parser.c | 113 ++++++++++++++++-----------------------
45
+ qobject/json-streamer.c | 19 +++----
46
+ 3 files changed, 62 insertions(+), 77 deletions(-)
47
+
48
+ diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
49
+ index e9f2937..09b3d3e 100644
50
+ --- a/include/qapi/qmp/json-streamer.h
51
+ +++ b/include/qapi/qmp/json-streamer.h
52
+ @@ -18,6 +18,13 @@
53
+ #include "glib-compat.h"
54
+ #include "qapi/qmp/json-lexer.h"
55
+
56
+ +typedef struct JSONToken {
57
+ + int type;
58
+ + int x;
59
+ + int y;
60
+ + char str[];
61
+ +} JSONToken;
62
+ +
63
+ typedef struct JSONMessageParser
64
+ {
65
+ void (*emit)(struct JSONMessageParser *parser, GQueue *tokens);
66
+ diff --git a/qobject/json-parser.c b/qobject/json-parser.c
67
+ index 6e5e257..944e1a1 100644
68
+ --- a/qobject/json-parser.c
69
+ +++ b/qobject/json-parser.c
70
+ @@ -23,11 +23,12 @@
71
+ #include "qapi/qmp/json-parser.h"
72
+ #include "qapi/qmp/json-lexer.h"
73
+ #include "qapi/qmp/qerror.h"
74
+ +#include "qapi/qmp/json-streamer.h"
75
+
76
+ typedef struct JSONParserContext
77
+ {
78
+ Error *err;
79
+ - QObject *current;
80
+ + JSONToken *current;
81
+ GQueue *buf;
82
+ } JSONParserContext;
83
+
84
+ @@ -45,27 +46,10 @@ typedef struct JSONParserContext
85
+ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap);
86
+
87
+ /**
88
+ - * Token manipulators
89
+ - *
90
+ - * tokens are dictionaries that contain a type, a string value, and geometry information
91
+ - * about a token identified by the lexer. These are routines that make working with
92
+ - * these objects a bit easier.
93
+ - */
94
+ -static const char *token_get_value(QObject *obj)
95
+ -{
96
+ - return qdict_get_str(qobject_to_qdict(obj), "token");
97
+ -}
98
+ -
99
+ -static JSONTokenType token_get_type(QObject *obj)
100
+ -{
101
+ - return qdict_get_int(qobject_to_qdict(obj), "type");
102
+ -}
103
+ -
104
+ -/**
105
+ * Error handler
106
+ */
107
+ static void GCC_FMT_ATTR(3, 4) parse_error(JSONParserContext *ctxt,
108
+ - QObject *token, const char *msg, ...)
109
+ + JSONToken *token, const char *msg, ...)
110
+ {
111
+ va_list ap;
112
+ char message[1024];
113
+ @@ -143,9 +127,10 @@ static int hex2decimal(char ch)
114
+ * \t
115
+ * \u four-hex-digits
116
+ */
117
+ -static QString *qstring_from_escaped_str(JSONParserContext *ctxt, QObject *token)
118
+ +static QString *qstring_from_escaped_str(JSONParserContext *ctxt,
119
+ + JSONToken *token)
120
+ {
121
+ - const char *ptr = token_get_value(token);
122
+ + const char *ptr = token->str;
123
+ QString *str;
124
+ int double_quote = 1;
125
+
126
+ @@ -241,19 +226,19 @@ out:
127
+ return NULL;
128
+ }
129
+
130
+ -/* Note: unless the token object returned by parser_context_peek_token
131
+ - * or parser_context_pop_token is explicitly incref'd, it will be
132
+ - * deleted as soon as parser_context_pop_token is called again.
133
+ +/* Note: the token object returned by parser_context_peek_token or
134
+ + * parser_context_pop_token is deleted as soon as parser_context_pop_token
135
+ + * is called again.
136
+ */
137
+ -static QObject *parser_context_pop_token(JSONParserContext *ctxt)
138
+ +static JSONToken *parser_context_pop_token(JSONParserContext *ctxt)
139
+ {
140
+ - qobject_decref(ctxt->current);
141
+ + g_free(ctxt->current);
142
+ assert(!g_queue_is_empty(ctxt->buf));
143
+ ctxt->current = g_queue_pop_head(ctxt->buf);
144
+ return ctxt->current;
145
+ }
146
+
147
+ -static QObject *parser_context_peek_token(JSONParserContext *ctxt)
148
+ +static JSONToken *parser_context_peek_token(JSONParserContext *ctxt)
149
+ {
150
+ assert(!g_queue_is_empty(ctxt->buf));
151
+ return g_queue_peek_head(ctxt->buf);
152
+ @@ -280,7 +265,7 @@ static void parser_context_free(JSONParserContext *ctxt)
153
+ while (!g_queue_is_empty(ctxt->buf)) {
154
+ parser_context_pop_token(ctxt);
155
+ }
156
+ - qobject_decref(ctxt->current);
157
+ + g_free(ctxt->current);
158
+ g_queue_free(ctxt->buf);
159
+ g_free(ctxt);
160
+ }
161
+ @@ -291,7 +276,8 @@ static void parser_context_free(JSONParserContext *ctxt)
162
+ */
163
+ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
164
+ {
165
+ - QObject *key = NULL, *token = NULL, *value, *peek;
166
+ + QObject *key = NULL, *value;
167
+ + JSONToken *peek, *token;
168
+
169
+ peek = parser_context_peek_token(ctxt);
170
+ if (peek == NULL) {
171
+ @@ -311,7 +297,7 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
172
+ goto out;
173
+ }
174
+
175
+ - if (token_get_type(token) != JSON_COLON) {
176
+ + if (token->type != JSON_COLON) {
177
+ parse_error(ctxt, token, "missing : in object pair");
178
+ goto out;
179
+ }
180
+ @@ -337,10 +323,10 @@ out:
181
+ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
182
+ {
183
+ QDict *dict = NULL;
184
+ - QObject *token, *peek;
185
+ + JSONToken *token, *peek;
186
+
187
+ token = parser_context_pop_token(ctxt);
188
+ - assert(token && token_get_type(token) == JSON_LCURLY);
189
+ + assert(token && token->type == JSON_LCURLY);
190
+
191
+ dict = qdict_new();
192
+
193
+ @@ -350,7 +336,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
194
+ goto out;
195
+ }
196
+
197
+ - if (token_get_type(peek) != JSON_RCURLY) {
198
+ + if (peek->type != JSON_RCURLY) {
199
+ if (parse_pair(ctxt, dict, ap) == -1) {
200
+ goto out;
201
+ }
202
+ @@ -361,8 +347,8 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
203
+ goto out;
204
+ }
205
+
206
+ - while (token_get_type(token) != JSON_RCURLY) {
207
+ - if (token_get_type(token) != JSON_COMMA) {
208
+ + while (token->type != JSON_RCURLY) {
209
+ + if (token->type != JSON_COMMA) {
210
+ parse_error(ctxt, token, "expected separator in dict");
211
+ goto out;
212
+ }
213
+ @@ -391,10 +377,10 @@ out:
214
+ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
215
+ {
216
+ QList *list = NULL;
217
+ - QObject *token, *peek;
218
+ + JSONToken *token, *peek;
219
+
220
+ token = parser_context_pop_token(ctxt);
221
+ - assert(token && token_get_type(token) == JSON_LSQUARE);
222
+ + assert(token && token->type == JSON_LSQUARE);
223
+
224
+ list = qlist_new();
225
+
226
+ @@ -404,7 +390,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
227
+ goto out;
228
+ }
229
+
230
+ - if (token_get_type(peek) != JSON_RSQUARE) {
231
+ + if (peek->type != JSON_RSQUARE) {
232
+ QObject *obj;
233
+
234
+ obj = parse_value(ctxt, ap);
235
+ @@ -421,8 +407,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
236
+ goto out;
237
+ }
238
+
239
+ - while (token_get_type(token) != JSON_RSQUARE) {
240
+ - if (token_get_type(token) != JSON_COMMA) {
241
+ + while (token->type != JSON_RSQUARE) {
242
+ + if (token->type != JSON_COMMA) {
243
+ parse_error(ctxt, token, "expected separator in list");
244
+ goto out;
245
+ }
246
+ @@ -454,49 +440,45 @@ out:
247
+
248
+ static QObject *parse_keyword(JSONParserContext *ctxt)
249
+ {
250
+ - QObject *token;
251
+ - const char *val;
252
+ + JSONToken *token;
253
+
254
+ token = parser_context_pop_token(ctxt);
255
+ - assert(token && token_get_type(token) == JSON_KEYWORD);
256
+ - val = token_get_value(token);
257
+ + assert(token && token->type == JSON_KEYWORD);
258
+
259
+ - if (!strcmp(val, "true")) {
260
+ + if (!strcmp(token->str, "true")) {
261
+ return QOBJECT(qbool_from_int(true));
262
+ - } else if (!strcmp(val, "false")) {
263
+ + } else if (!strcmp(token->str, "false")) {
264
+ return QOBJECT(qbool_from_int(false));
265
+ }
266
+ - parse_error(ctxt, token, "invalid keyword '%s'", val);
267
+ + parse_error(ctxt, token, "invalid keyword '%s'", token->str);
268
+ return NULL;
269
+ }
270
+
271
+ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
272
+ {
273
+ - QObject *token;
274
+ - const char *val;
275
+ + JSONToken *token;
276
+
277
+ if (ap == NULL) {
278
+ return NULL;
279
+ }
280
+
281
+ token = parser_context_pop_token(ctxt);
282
+ - assert(token && token_get_type(token) == JSON_ESCAPE);
283
+ - val = token_get_value(token);
284
+ + assert(token && token->type == JSON_ESCAPE);
285
+
286
+ - if (!strcmp(val, "%p")) {
287
+ + if (!strcmp(token->str, "%p")) {
288
+ return va_arg(*ap, QObject *);
289
+ - } else if (!strcmp(val, "%i")) {
290
+ + } else if (!strcmp(token->str, "%i")) {
291
+ return QOBJECT(qbool_from_int(va_arg(*ap, int)));
292
+ - } else if (!strcmp(val, "%d")) {
293
+ + } else if (!strcmp(token->str, "%d")) {
294
+ return QOBJECT(qint_from_int(va_arg(*ap, int)));
295
+ - } else if (!strcmp(val, "%ld")) {
296
+ + } else if (!strcmp(token->str, "%ld")) {
297
+ return QOBJECT(qint_from_int(va_arg(*ap, long)));
298
+ - } else if (!strcmp(val, "%lld") ||
299
+ - !strcmp(val, "%I64d")) {
300
+ + } else if (!strcmp(token->str, "%lld") ||
301
+ + !strcmp(token->str, "%I64d")) {
302
+ return QOBJECT(qint_from_int(va_arg(*ap, long long)));
303
+ - } else if (!strcmp(val, "%s")) {
304
+ + } else if (!strcmp(token->str, "%s")) {
305
+ return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
306
+ - } else if (!strcmp(val, "%f")) {
307
+ + } else if (!strcmp(token->str, "%f")) {
308
+ return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
309
+ }
310
+ return NULL;
311
+ @@ -504,12 +486,12 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
312
+
313
+ static QObject *parse_literal(JSONParserContext *ctxt)
314
+ {
315
+ - QObject *token;
316
+ + JSONToken *token;
317
+
318
+ token = parser_context_pop_token(ctxt);
319
+ assert(token);
320
+
321
+ - switch (token_get_type(token)) {
322
+ + switch (token->type) {
323
+ case JSON_STRING:
324
+ return QOBJECT(qstring_from_escaped_str(ctxt, token));
325
+ case JSON_INTEGER: {
326
+ @@ -528,7 +510,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
327
+ int64_t value;
328
+
329
+ errno = 0; /* strtoll doesn't set errno on success */
330
+ - value = strtoll(token_get_value(token), NULL, 10);
331
+ + value = strtoll(token->str, NULL, 10);
332
+ if (errno != ERANGE) {
333
+ return QOBJECT(qint_from_int(value));
334
+ }
335
+ @@ -536,8 +518,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
336
+ }
337
+ case JSON_FLOAT:
338
+ /* FIXME dependent on locale */
339
+ - return QOBJECT(qfloat_from_double(strtod(token_get_value(token),
340
+ - NULL)));
341
+ + return QOBJECT(qfloat_from_double(strtod(token->str, NULL)));
342
+ default:
343
+ abort();
344
+ }
345
+ @@ -545,7 +526,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
346
+
347
+ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
348
+ {
349
+ - QObject *token;
350
+ + JSONToken *token;
351
+
352
+ token = parser_context_peek_token(ctxt);
353
+ if (token == NULL) {
354
+ @@ -553,7 +534,7 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
355
+ return NULL;
356
+ }
357
+
358
+ - switch (token_get_type(token)) {
359
+ + switch (token->type) {
360
+ case JSON_LCURLY:
361
+ return parse_object(ctxt, ap);
362
+ case JSON_LSQUARE:
363
+ diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
364
+ index f7a3e78..e87230d 100644
365
+ --- a/qobject/json-streamer.c
366
+ +++ b/qobject/json-streamer.c
367
+ @@ -11,10 +11,6 @@
368
+ *
369
+ */
370
+
371
+ -#include "qapi/qmp/qlist.h"
372
+ -#include "qapi/qmp/qstring.h"
373
+ -#include "qapi/qmp/qint.h"
374
+ -#include "qapi/qmp/qdict.h"
375
+ #include "qemu-common.h"
376
+ #include "qapi/qmp/json-lexer.h"
377
+ #include "qapi/qmp/json-streamer.h"
378
+ @@ -34,7 +30,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
379
+ JSONTokenType type, int x, int y)
380
+ {
381
+ JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
382
+ - QDict *dict;
383
+ + JSONToken *token;
384
+
385
+ switch (type) {
386
+ case JSON_LCURLY:
387
+ @@ -53,15 +49,16 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
388
+ break;
389
+ }
390
+
391
+ - dict = qdict_new();
392
+ - qdict_put(dict, "type", qint_from_int(type));
393
+ - qdict_put(dict, "token", qstring_from_str(input->str));
394
+ - qdict_put(dict, "x", qint_from_int(x));
395
+ - qdict_put(dict, "y", qint_from_int(y));
396
+ + token = g_malloc(sizeof(JSONToken) + input->len + 1);
397
+ + token->type = type;
398
+ + memcpy(token->str, input->str, input->len);
399
+ + token->str[input->len] = 0;
400
+ + token->x = x;
401
+ + token->y = y;
402
+
403
+ parser->token_size += input->len;
404
+
405
+ - g_queue_push_tail(parser->tokens, dict);
406
+ + g_queue_push_tail(parser->tokens, token);
407
+
408
+ if (type == JSON_ERROR) {
409
+ goto out_emit_bad;
410
+ --
411
+ 1.8.3.1
412
+
SOURCES/kvm-qxl-Fix-new-function-name-for-spice-server-library.patch ADDED
@@ -0,0 +1,57 @@
1
+ From ac053d6013f7fab73f66db60462c388bea21b714 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <ac053d6013f7fab73f66db60462c388bea21b714.1464449390.git.jen@redhat.com>
3
+ In-Reply-To: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
4
+ References: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
5
+ From: Gerd Hoffmann <kraxel@redhat.com>
6
+ Date: Fri, 13 May 2016 16:09:29 -0400
7
+ Subject: [CHANGE 2/3] qxl: Fix new function name for spice-server library
8
+ MIME-Version: 1.0
9
+ Content-Type: text/plain; charset=UTF-8
10
+ Content-Transfer-Encoding: 8bit
11
+ To: rhvirt-patches@redhat.com,
12
+ jen@redhat.com
13
+
14
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
15
+ Message-id: <1463155769-32352-3-git-send-email-kraxel@redhat.com>
16
+ Patchwork-id: 70403
17
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 2/2] qxl: Fix new function name for spice-server library
18
+ Bugzilla: 1283198
19
+ RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
20
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
21
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
22
+
23
+ From: Frediano Ziglio <fziglio@redhat.com>
24
+
25
+ The new spice-server function to limit the number of monitors (0.12.6)
26
+ changed while development from spice_qxl_set_monitors_config_limit to
27
+ spice_qxl_max_monitors (accepted upstream).
28
+ By mistake I post patch with former name.
29
+ This patch fix the function name.
30
+
31
+ Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
32
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
33
+ Acked-by: Martin Kletzander <mkletzan@redhat.com>
34
+ Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
35
+ (cherry picked from commit a52b2cbf218d52f9e357961acb271a98a2bdff71)
36
+ Signed-off-by: Jeff E. Nelson <jen@redhat.com>
37
+ ---
38
+ hw/display/qxl.c | 3 +--
39
+ 1 file changed, 1 insertion(+), 2 deletions(-)
40
+
41
+ diff --git a/hw/display/qxl.c b/hw/display/qxl.c
42
+ index 1f6a303..748dfce 100644
43
+ --- a/hw/display/qxl.c
44
+ +++ b/hw/display/qxl.c
45
+ @@ -268,8 +268,7 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
46
+ } else {
47
+ #if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
48
+ if (qxl->max_outputs) {
49
+ - spice_qxl_set_monitors_config_limit(&qxl->ssd.qxl,
50
+ - qxl->max_outputs);
51
+ + spice_qxl_set_max_monitors(&qxl->ssd.qxl, qxl->max_outputs);
52
+ }
53
+ #endif
54
+ qxl->guest_monitors_config = qxl->ram->monitors_config;
55
+ --
56
+ 2.5.5
57
+
SOURCES/kvm-qxl-allow-to-specify-head-limit-to-qxl-driver.patch ADDED
@@ -0,0 +1,120 @@
1
+ From c7936395ecf322b3de37662c7c6b772e36866cc7 Mon Sep 17 00:00:00 2001
2
+ Message-Id: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
3
+ From: Gerd Hoffmann <kraxel@redhat.com>
4
+ Date: Fri, 13 May 2016 16:09:28 -0400
5
+ Subject: [CHANGE 1/3] qxl: allow to specify head limit to qxl driver
6
+ MIME-Version: 1.0
7
+ Content-Type: text/plain; charset=UTF-8
8
+ Content-Transfer-Encoding: 8bit
9
+ To: rhvirt-patches@redhat.com,
10
+ jen@redhat.com
11
+
12
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
13
+ Message-id: <1463155769-32352-2-git-send-email-kraxel@redhat.com>
14
+ Patchwork-id: 70404
15
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/2] qxl: allow to specify head limit to qxl driver
16
+ Bugzilla: 1283198
17
+ RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
18
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
19
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
20
+
21
+ From: Frediano Ziglio <fziglio@redhat.com>
22
+
23
+ This patch allow to limit number of heads using qxl driver. By default
24
+ qxl driver is not limited on any kind on head use so can decide to use
25
+ as much heads.
26
+
27
+ libvirt has this as a video card parameter (actually set to 1 but not
28
+ used). This parameter will allow to limit setting a use can do (which
29
+ could be confusing).
30
+
31
+ Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
32
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
33
+ (cherry picked from commit 567161fdd47aeb6987e700702f6bbfef04ae0236)
34
+ Signed-off-by: Jeff E. Nelson <jen@redhat.com>
35
+ ---
36
+ hw/display/qxl.c | 26 +++++++++++++++++++++-----
37
+ hw/display/qxl.h | 3 +++
38
+ 2 files changed, 24 insertions(+), 5 deletions(-)
39
+
40
+ diff --git a/hw/display/qxl.c b/hw/display/qxl.c
41
+ index f11210c..1f6a303 100644
42
+ --- a/hw/display/qxl.c
43
+ +++ b/hw/display/qxl.c
44
+ @@ -266,6 +266,12 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
45
+ QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
46
+ 0));
47
+ } else {
48
+ +#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
49
+ + if (qxl->max_outputs) {
50
+ + spice_qxl_set_monitors_config_limit(&qxl->ssd.qxl,
51
+ + qxl->max_outputs);
52
+ + }
53
+ +#endif
54
+ qxl->guest_monitors_config = qxl->ram->monitors_config;
55
+ spice_qxl_monitors_config_async(&qxl->ssd.qxl,
56
+ qxl->ram->monitors_config,
57
+ @@ -991,6 +997,7 @@ static int interface_client_monitors_config(QXLInstance *sin,
58
+ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
59
+ QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
60
+ int i;
61
+ + unsigned max_outputs = ARRAY_SIZE(rom->client_monitors_config.heads);
62
+
63
+ if (qxl->revision < 4) {
64
+ trace_qxl_client_monitors_config_unsupported_by_device(qxl->id,
65
+ @@ -1013,17 +1020,23 @@ static int interface_client_monitors_config(QXLInstance *sin,
66
+ if (!monitors_config) {
67
+ return 1;
68
+ }
69
+ +
70
+ +#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
71
+ + /* limit number of outputs based on setting limit */
72
+ + if (qxl->max_outputs && qxl->max_outputs <= max_outputs) {
73
+ + max_outputs = qxl->max_outputs;
74
+ + }
75
+ +#endif
76
+ +
77
+ memset(&rom->client_monitors_config, 0,
78
+ sizeof(rom->client_monitors_config));
79
+ rom->client_monitors_config.count = monitors_config->num_of_monitors;
80
+ /* monitors_config->flags ignored */
81
+ - if (rom->client_monitors_config.count >=
82
+ - ARRAY_SIZE(rom->client_monitors_config.heads)) {
83
+ + if (rom->client_monitors_config.count >= max_outputs) {
84
+ trace_qxl_client_monitors_config_capped(qxl->id,
85
+ monitors_config->num_of_monitors,
86
+ - ARRAY_SIZE(rom->client_monitors_config.heads));
87
+ - rom->client_monitors_config.count =
88
+ - ARRAY_SIZE(rom->client_monitors_config.heads);
89
+ + max_outputs);
90
+ + rom->client_monitors_config.count = max_outputs;
91
+ }
92
+ for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
93
+ VDAgentMonConfig *monitor = &monitors_config->monitors[i];
94
+ @@ -2294,6 +2307,9 @@ static Property qxl_properties[] = {
95
+ DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
96
+ DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
97
+ DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
98
+ +#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
99
+ + DEFINE_PROP_UINT16("max_outputs", PCIQXLDevice, max_outputs, 0),
100
+ +#endif
101
+ DEFINE_PROP_END_OF_LIST(),
102
+ };
103
+
104
+ diff --git a/hw/display/qxl.h b/hw/display/qxl.h
105
+ index 5da33e2..5247ce9 100644
106
+ --- a/hw/display/qxl.h
107
+ +++ b/hw/display/qxl.h
108
+ @@ -95,6 +95,9 @@ typedef struct PCIQXLDevice {
109
+ QXLModes *modes;
110
+ uint32_t rom_size;
111
+ MemoryRegion rom_bar;
112
+ +#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
113
+ + uint16_t max_outputs;
114
+ +#endif
115
+
116
+ /* vram pci bar */
117
+ uint32_t vram_size;
118
+ --
119
+ 2.5.5
120
+
SOURCES/kvm-qxl-factor-out-qxl_get_check_slot_offset.patch ADDED
@@ -0,0 +1,108 @@
1
+ From 24a604e857d2797c3da9852bcbea75f2f9e6961c Mon Sep 17 00:00:00 2001
2
+ From: Gerd Hoffmann <kraxel@redhat.com>
3
+ Date: Fri, 22 Jul 2016 09:34:38 +0200
4
+ Subject: [PATCH 1/4] qxl: factor out qxl_get_check_slot_offset
5
+
6
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
+ Message-id: <1469180081-28522-2-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 71317
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/4] qxl: factor out qxl_get_check_slot_offset
10
+ Bugzilla: 1355730
11
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+
15
+ New helper function which translates a qxl physical address into
16
+ memory slot and offset. Also applies sanity checks. Factored out
17
+ from qxl_phys2virt. No functional change.
18
+
19
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
20
+ Message-id: 1466597244-5938-1-git-send-email-kraxel@redhat.com
21
+ (cherry picked from commit 726bdf653aca9b87e28c9a56dd94c4667ddfacbc)
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+ ---
24
+ hw/display/qxl.c | 59 ++++++++++++++++++++++++++++++++++++--------------------
25
+ 1 file changed, 38 insertions(+), 21 deletions(-)
26
+
27
+ diff --git a/hw/display/qxl.c b/hw/display/qxl.c
28
+ index 748dfce..5e1ecd8 100644
29
+ --- a/hw/display/qxl.c
30
+ +++ b/hw/display/qxl.c
31
+ @@ -1326,36 +1326,53 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
32
+ }
33
+
34
+ /* can be also called from spice server thread context */
35
+ -void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
36
+ +static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
37
+ + uint32_t *s, uint64_t *o)
38
+ {
39
+ uint64_t phys = le64_to_cpu(pqxl);
40
+ uint32_t slot = (phys >> (64 - 8)) & 0xff;
41
+ uint64_t offset = phys & 0xffffffffffff;
42
+
43
+ - switch (group_id) {
44
+ - case MEMSLOT_GROUP_HOST:
45
+ - return (void *)(intptr_t)offset;
46
+ - case MEMSLOT_GROUP_GUEST:
47
+ - if (slot >= NUM_MEMSLOTS) {
48
+ - qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
49
+ - NUM_MEMSLOTS);
50
+ - return NULL;
51
+ - }
52
+ - if (!qxl->guest_slots[slot].active) {
53
+ - qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
54
+ - return NULL;
55
+ - }
56
+ - if (offset < qxl->guest_slots[slot].delta) {
57
+ - qxl_set_guest_bug(qxl,
58
+ + if (slot >= NUM_MEMSLOTS) {
59
+ + qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
60
+ + NUM_MEMSLOTS);
61
+ + return false;
62
+ + }
63
+ + if (!qxl->guest_slots[slot].active) {
64
+ + qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
65
+ + return false;
66
+ + }
67
+ + if (offset < qxl->guest_slots[slot].delta) {
68
+ + qxl_set_guest_bug(qxl,
69
+ "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
70
+ slot, offset, qxl->guest_slots[slot].delta);
71
+ - return NULL;
72
+ - }
73
+ - offset -= qxl->guest_slots[slot].delta;
74
+ - if (offset > qxl->guest_slots[slot].size) {
75
+ - qxl_set_guest_bug(qxl,
76
+ + return false;
77
+ + }
78
+ + offset -= qxl->guest_slots[slot].delta;
79
+ + if (offset > qxl->guest_slots[slot].size) {
80
+ + qxl_set_guest_bug(qxl,
81
+ "slot %d offset %"PRIu64" > size %"PRIu64"\n",
82
+ slot, offset, qxl->guest_slots[slot].size);
83
+ + return false;
84
+ + }
85
+ +
86
+ + *s = slot;
87
+ + *o = offset;
88
+ + return true;
89
+ +}
90
+ +
91
+ +/* can be also called from spice server thread context */
92
+ +void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
93
+ +{
94
+ + uint64_t offset;
95
+ + uint32_t slot;
96
+ +
97
+ + switch (group_id) {
98
+ + case MEMSLOT_GROUP_HOST:
99
+ + offset = le64_to_cpu(pqxl) & 0xffffffffffff;
100
+ + return (void *)(intptr_t)offset;
101
+ + case MEMSLOT_GROUP_GUEST:
102
+ + if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
103
+ return NULL;
104
+ }
105
+ return qxl->guest_slots[slot].ptr + offset;
106
+ --
107
+ 1.8.3.1
108
+
SOURCES/kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch ADDED
@@ -0,0 +1,79 @@
1
+ From e7fe5cf70d63552006e8c9eb660db95279f2a3a9 Mon Sep 17 00:00:00 2001
2
+ From: Gerd Hoffmann <kraxel@redhat.com>
3
+ Date: Fri, 22 Jul 2016 09:34:41 +0200
4
+ Subject: [PATCH 4/4] qxl: fix qxl_set_dirty call in qxl_dirty_one_surface
5
+
6
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
+ Message-id: <1469180081-28522-5-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 71316
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 4/4] qxl: fix qxl_set_dirty call in qxl_dirty_one_surface
10
+ Bugzilla: 1355730
11
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+
15
+ qxl_set_dirty() expects start and end as range specification.
16
+ qxl_dirty_one_surface passes 'size' instead of 'offset + size' as end
17
+ parameter. Fix that. Also use uint64_t everywhere while being at it.
18
+
19
+ Bug was added by "e25139b qxl: set only off-screen surfaces dirty instead
20
+ of the whole vram" and carried forward unnoticed by "5cdc402 qxl: fix
21
+ surface migration".
22
+
23
+ Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
24
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
25
+ Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
26
+ Message-id: 1468413187-22071-1-git-send-email-kraxel@redhat.com
27
+ (cherry picked from commit e0127d2eec9cd5676ea9f3c47c2a7579a02c0466)
28
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
29
+
30
+ Conflicts:
31
+ hw/display/trace-events
32
+ ---
33
+ hw/display/qxl.c | 11 ++++++-----
34
+ trace-events | 2 +-
35
+ 2 files changed, 7 insertions(+), 6 deletions(-)
36
+
37
+ diff --git a/hw/display/qxl.c b/hw/display/qxl.c
38
+ index d65c830..f762439 100644
39
+ --- a/hw/display/qxl.c
40
+ +++ b/hw/display/qxl.c
41
+ @@ -1825,16 +1825,17 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
42
+ static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
43
+ uint32_t height, int32_t stride)
44
+ {
45
+ - uint64_t offset;
46
+ - uint32_t slot, size;
47
+ + uint64_t offset, size;
48
+ + uint32_t slot;
49
+ bool rc;
50
+
51
+ rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
52
+ assert(rc == true);
53
+ - size = height * abs(stride);
54
+ - trace_qxl_surfaces_dirty(qxl->id, (int)offset, size);
55
+ + size = (uint64_t)height * abs(stride);
56
+ + trace_qxl_surfaces_dirty(qxl->id, offset, size);
57
+ qxl_set_dirty(qxl->guest_slots[slot].mr,
58
+ - qxl->guest_slots[slot].offset + offset, size);
59
+ + qxl->guest_slots[slot].offset + offset,
60
+ + qxl->guest_slots[slot].offset + offset + size);
61
+ }
62
+
63
+ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
64
+ diff --git a/trace-events b/trace-events
65
+ index 4da84b2..af5147a 100644
66
+ --- a/trace-events
67
+ +++ b/trace-events
68
+ @@ -1078,7 +1078,7 @@ qxl_spice_reset_image_cache(int qid) "%d"
69
+ qxl_spice_reset_memslots(int qid) "%d"
70
+ qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
71
+ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
72
+ -qxl_surfaces_dirty(int qid, int offset, int size) "%d offset=%d size=%d"
73
+ +qxl_surfaces_dirty(int qid, uint64_t offset, uint64_t size) "%d offset=0x%"PRIx64" size=0x%"PRIx64
74
+ qxl_send_events(int qid, uint32_t events) "%d %d"
75
+ qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
76
+ qxl_set_guest_bug(int qid) "%d"
77
+ --
78
+ 1.8.3.1
79
+
SOURCES/kvm-qxl-fix-surface-migration.patch ADDED
@@ -0,0 +1,124 @@
1
+ From 13bf417cd4063f5db2f0a79265745481d4c69d0d Mon Sep 17 00:00:00 2001
2
+ From: Gerd Hoffmann <kraxel@redhat.com>
3
+ Date: Fri, 22 Jul 2016 09:34:40 +0200
4
+ Subject: [PATCH 3/4] qxl: fix surface migration
5
+
6
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
+ Message-id: <1469180081-28522-4-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 71315
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 3/4] qxl: fix surface migration
10
+ Bugzilla: 1355730
11
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+
15
+ Create a helper function qxl_dirty_one_surface() to mark a single qxl
16
+ surface as dirty. Use the new qxl_get_check_slot_offset function and
17
+ lookup the memory region from the slot instead of assuming the surface
18
+ is stored in vram.
19
+
20
+ Use the new helper function in qxl_dirty_surfaces, for both primary and
21
+ off-screen surfaces. For off-screen surfaces this is no functional
22
+ change. For primary surfaces this will dirty only the memory actually
23
+ used instead of the whole surface0 region. It will also work correctly
24
+ in case the guest places the primary surface in vram instead of the
25
+ surface0 region (linux kms driver does that).
26
+
27
+ https://bugzilla.redhat.com/show_bug.cgi?id=1235732
28
+
29
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
30
+ Message-id: 1466597244-5938-3-git-send-email-kraxel@redhat.com
31
+ (cherry picked from commit 1331eab216c9dc4e50a48a34d14926b31a7fd611)
32
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
33
+
34
+ Conflicts:
35
+ hw/display/trace-events
36
+ ---
37
+ hw/display/qxl.c | 37 +++++++++++++++++++++----------------
38
+ trace-events | 2 +-
39
+ 2 files changed, 22 insertions(+), 17 deletions(-)
40
+
41
+ diff --git a/hw/display/qxl.c b/hw/display/qxl.c
42
+ index de5770e..d65c830 100644
43
+ --- a/hw/display/qxl.c
44
+ +++ b/hw/display/qxl.c
45
+ @@ -1822,9 +1822,23 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
46
+ }
47
+ }
48
+
49
+ +static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
50
+ + uint32_t height, int32_t stride)
51
+ +{
52
+ + uint64_t offset;
53
+ + uint32_t slot, size;
54
+ + bool rc;
55
+ +
56
+ + rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
57
+ + assert(rc == true);
58
+ + size = height * abs(stride);
59
+ + trace_qxl_surfaces_dirty(qxl->id, (int)offset, size);
60
+ + qxl_set_dirty(qxl->guest_slots[slot].mr,
61
+ + qxl->guest_slots[slot].offset + offset, size);
62
+ +}
63
+ +
64
+ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
65
+ {
66
+ - uintptr_t vram_start;
67
+ int i;
68
+
69
+ if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
70
+ @@ -1832,16 +1846,13 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
71
+ }
72
+
73
+ /* dirty the primary surface */
74
+ - qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
75
+ - qxl->shadow_rom.surface0_area_size);
76
+ -
77
+ - vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
78
+ + qxl_dirty_one_surface(qxl, qxl->guest_primary.surface.mem,
79
+ + qxl->guest_primary.surface.height,
80
+ + qxl->guest_primary.surface.stride);
81
+
82
+ /* dirty the off-screen surfaces */
83
+ for (i = 0; i < qxl->ssd.num_surfaces; i++) {
84
+ QXLSurfaceCmd *cmd;
85
+ - intptr_t surface_offset;
86
+ - int surface_size;
87
+
88
+ if (qxl->guest_surfaces.cmds[i] == 0) {
89
+ continue;
90
+ @@ -1851,15 +1862,9 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
91
+ MEMSLOT_GROUP_GUEST);
92
+ assert(cmd);
93
+ assert(cmd->type == QXL_SURFACE_CMD_CREATE);
94
+ - surface_offset = (intptr_t)qxl_phys2virt(qxl,
95
+ - cmd->u.surface_create.data,
96
+ - MEMSLOT_GROUP_GUEST);
97
+ - assert(surface_offset);
98
+ - surface_offset -= vram_start;
99
+ - surface_size = cmd->u.surface_create.height *
100
+ - abs(cmd->u.surface_create.stride);
101
+ - trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
102
+ - qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
103
+ + qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,
104
+ + cmd->u.surface_create.height,
105
+ + cmd->u.surface_create.stride);
106
+ }
107
+ }
108
+
109
+ diff --git a/trace-events b/trace-events
110
+ index b43132c..4da84b2 100644
111
+ --- a/trace-events
112
+ +++ b/trace-events
113
+ @@ -1078,7 +1078,7 @@ qxl_spice_reset_image_cache(int qid) "%d"
114
+ qxl_spice_reset_memslots(int qid) "%d"
115
+ qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
116
+ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
117
+ -qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
118
+ +qxl_surfaces_dirty(int qid, int offset, int size) "%d offset=%d size=%d"
119
+ qxl_send_events(int qid, uint32_t events) "%d %d"
120
+ qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
121
+ qxl_set_guest_bug(int qid) "%d"
122
+ --
123
+ 1.8.3.1
124
+
SOURCES/kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch ADDED
@@ -0,0 +1,109 @@
1
+ From 8f25ff7e1496ce8a26edacfa01c64f3a98c564a0 Mon Sep 17 00:00:00 2001
2
+ From: Gerd Hoffmann <kraxel@redhat.com>
3
+ Date: Fri, 22 Jul 2016 09:34:39 +0200
4
+ Subject: [PATCH 2/4] qxl: store memory region and offset instead of pointer
5
+ for guest slots
6
+
7
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
8
+ Message-id: <1469180081-28522-3-git-send-email-kraxel@redhat.com>
9
+ Patchwork-id: 71314
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/4] qxl: store memory region and offset instead of pointer for guest slots
11
+ Bugzilla: 1355730
12
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
13
+ RH-Acked-by: John Snow <jsnow@redhat.com>
14
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
15
+
16
+ Store MemoryRegion and offset instead of a pointer for each qxl memory
17
+ slot, so we can easily figure in which memory region an qxl object
18
+ stored.
19
+
20
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
21
+ Message-id: 1466597244-5938-2-git-send-email-kraxel@redhat.com
22
+ (cherry picked from commit 3cb5158f15604a9f50287f2f06777d5835ff4c15)
23
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
24
+ ---
25
+ hw/display/qxl.c | 15 +++++++++++----
26
+ hw/display/qxl.h | 3 ++-
27
+ 2 files changed, 13 insertions(+), 5 deletions(-)
28
+
29
+ diff --git a/hw/display/qxl.c b/hw/display/qxl.c
30
+ index 5e1ecd8..de5770e 100644
31
+ --- a/hw/display/qxl.c
32
+ +++ b/hw/display/qxl.c
33
+ @@ -1232,6 +1232,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
34
+ int pci_region;
35
+ pcibus_t pci_start;
36
+ pcibus_t pci_end;
37
+ + MemoryRegion *mr;
38
+ intptr_t virt_start;
39
+ QXLDevMemSlot memslot;
40
+ int i;
41
+ @@ -1278,11 +1279,11 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
42
+
43
+ switch (pci_region) {
44
+ case QXL_RAM_RANGE_INDEX:
45
+ - virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
46
+ + mr = &d->vga.vram;
47
+ break;
48
+ case QXL_VRAM_RANGE_INDEX:
49
+ case 4 /* vram 64bit */:
50
+ - virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
51
+ + mr = &d->vram_bar;
52
+ break;
53
+ default:
54
+ /* should not happen */
55
+ @@ -1290,6 +1291,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
56
+ return 1;
57
+ }
58
+
59
+ + virt_start = (intptr_t)memory_region_get_ram_ptr(mr);
60
+ memslot.slot_id = slot_id;
61
+ memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
62
+ memslot.virt_start = virt_start + (guest_start - pci_start);
63
+ @@ -1299,7 +1301,8 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
64
+ qxl_rom_set_dirty(d);
65
+
66
+ qemu_spice_add_memslot(&d->ssd, &memslot, async);
67
+ - d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
68
+ + d->guest_slots[slot_id].mr = mr;
69
+ + d->guest_slots[slot_id].offset = memslot.virt_start - virt_start;
70
+ d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
71
+ d->guest_slots[slot_id].delta = delta;
72
+ d->guest_slots[slot_id].active = 1;
73
+ @@ -1366,6 +1369,7 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
74
+ {
75
+ uint64_t offset;
76
+ uint32_t slot;
77
+ + void *ptr;
78
+
79
+ switch (group_id) {
80
+ case MEMSLOT_GROUP_HOST:
81
+ @@ -1375,7 +1379,10 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
82
+ if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
83
+ return NULL;
84
+ }
85
+ - return qxl->guest_slots[slot].ptr + offset;
86
+ + ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
87
+ + ptr += qxl->guest_slots[slot].offset;
88
+ + ptr += offset;
89
+ + return ptr;
90
+ }
91
+ return NULL;
92
+ }
93
+ diff --git a/hw/display/qxl.h b/hw/display/qxl.h
94
+ index 5247ce9..f3f51e2 100644
95
+ --- a/hw/display/qxl.h
96
+ +++ b/hw/display/qxl.h
97
+ @@ -49,7 +49,8 @@ typedef struct PCIQXLDevice {
98
+
99
+ struct guest_slots {
100
+ QXLMemSlot slot;
101
+ - void *ptr;
102
+ + MemoryRegion *mr;
103
+ + uint64_t offset;
104
+ uint64_t size;
105
+ uint64_t delta;
106
+ uint32_t active;
107
+ --
108
+ 1.8.3.1
109
+
SOURCES/kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch ADDED
@@ -0,0 +1,67 @@
1
+ From 52288902dd647cbcfa470a11867163a6e5983297 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 11 Jul 2016 05:33:38 +0200
4
+ Subject: [PATCH 5/7] raw-posix: Fetch max sectors for host block device
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1468215219-30793-6-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 71109
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 5/6] raw-posix: Fetch max sectors for host block device
10
+ Bugzilla: 1318199
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ This is sometimes a useful value we should count in.
16
+
17
+ Signed-off-by: Fam Zheng <famz@redhat.com>
18
+ Reviewed-by: Eric Blake <eblake@redhat.com>
19
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
+ (cherry picked from commit 6f6071745bd0366221f5a0160ed7d18d0e38b9f7)
21
+ Signed-off-by: Fam Zheng <famz@redhat.com>
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+ ---
24
+ block/raw-posix.c | 24 ++++++++++++++++++++++++
25
+ 1 file changed, 24 insertions(+)
26
+
27
+ diff --git a/block/raw-posix.c b/block/raw-posix.c
28
+ index 92fcb6c..ed97bd4 100644
29
+ --- a/block/raw-posix.c
30
+ +++ b/block/raw-posix.c
31
+ @@ -587,9 +587,33 @@ static void raw_reopen_abort(BDRVReopenState *state)
32
+ state->opaque = NULL;
33
+ }
34
+
35
+ +static int hdev_get_max_transfer_length(int fd)
36
+ +{
37
+ +#ifdef BLKSECTGET
38
+ + int max_sectors = 0;
39
+ + if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
40
+ + return max_sectors;
41
+ + } else {
42
+ + return -errno;
43
+ + }
44
+ +#else
45
+ + return -ENOSYS;
46
+ +#endif
47
+ +}
48
+ +
49
+ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
50
+ {
51
+ BDRVRawState *s = bs->opaque;
52
+ + struct stat st;
53
+ +
54
+ + if (!fstat(s->fd, &st)) {
55
+ + if (S_ISBLK(st.st_mode)) {
56
+ + int ret = hdev_get_max_transfer_length(s->fd);
57
+ + if (ret >= 0) {
58
+ + bs->bl.max_transfer_length = ret;
59
+ + }
60
+ + }
61
+ + }
62
+
63
+ raw_probe_alignment(bs, s->fd, errp);
64
+ bs->bl.opt_mem_alignment = s->buf_align;
65
+ --
66
+ 1.8.3.1
67
+
SOURCES/kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch CHANGED
@@ -1,13 +1,13 @@
1
- From 1a4a13c7c0f05f5a423c09607c7ef5151d315242 Mon Sep 17 00:00:00 2001
1
+ From 4237964a9f433faaf643166a8ce9c070dc4cf165 Mon Sep 17 00:00:00 2001
2
2
From: Max Reitz <mreitz@redhat.com>
3
- Date: Sat, 16 Jan 2016 14:02:12 +0100
3
+ Date: Thu, 14 Jan 2016 15:10:31 +0100
4
4
Subject: [PATCH] raw-posix: Fix .bdrv_co_get_block_status() for unaligned
5
5
image size
6
6
7
- Message-id: <1452952932-2466-2-git-send-email-mreitz@redhat.com>
8
- Patchwork-id: 68783
9
- O-Subject: [RHEL-7.2.z qemu-kvm PATCH 1/1] raw-posix: Fix .bdrv_co_get_block_status() for unaligned image size
10
- Bugzilla: 1298828
7
+ Message-id: <1452784231-14211-2-git-send-email-mreitz@redhat.com>
8
+ Patchwork-id: 68756
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] raw-posix: Fix .bdrv_co_get_block_status() for unaligned image size
10
+ Bugzilla: 1283116
11
11
RH-Acked-by: Fam Zheng <famz@redhat.com>
12
12
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13
13
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
SOURCES/kvm-rbd-fix-ceph-settings-precedence.patch CHANGED
@@ -1,12 +1,12 @@
1
- From a66fe0ea2e09b8d82a2d8940632ac06ee8bcc579 Mon Sep 17 00:00:00 2001
1
+ From 109d7dedc79629f58fd9b685ccd9990b90f374e9 Mon Sep 17 00:00:00 2001
2
2
From: Stefan Hajnoczi <stefanha@redhat.com>
3
3
Date: Thu, 5 Nov 2015 15:20:58 +0100
4
- Subject: [PATCH 2/2] rbd: fix ceph settings precedence
4
+ Subject: [PATCH 3/6] rbd: fix ceph settings precedence
5
5
6
6
Message-id: <1446736858-29005-3-git-send-email-stefanha@redhat.com>
7
7
Patchwork-id: 68294
8
8
O-Subject: [RHEL-7.2.z qemu-kvm PATCH 2/2] rbd: fix ceph settings precedence
9
- Bugzilla: 1279389
9
+ Bugzilla: 1277248 1279389
10
10
RH-Acked-by: Max Reitz <mreitz@redhat.com>
11
11
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
12
12
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
SOURCES/kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch CHANGED
@@ -1,12 +1,12 @@
1
- From 6f293e47850a873d0ccc39882be7b3ef6e1043b6 Mon Sep 17 00:00:00 2001
1
+ From 23bc583f18eb8ffc28604a4ae42e2f7a55b31c3e Mon Sep 17 00:00:00 2001
2
2
From: Stefan Hajnoczi <stefanha@redhat.com>
3
3
Date: Thu, 5 Nov 2015 15:20:57 +0100
4
- Subject: [PATCH 1/2] rbd: make qemu's cache setting override any ceph setting
4
+ Subject: [PATCH 2/6] rbd: make qemu's cache setting override any ceph setting
5
5
6
6
Message-id: <1446736858-29005-2-git-send-email-stefanha@redhat.com>
7
7
Patchwork-id: 68293
8
8
O-Subject: [RHEL-7.2.z qemu-kvm PATCH 1/2] rbd: make qemu's cache setting override any ceph setting
9
- Bugzilla: 1279389
9
+ Bugzilla: 1277248
10
10
RH-Acked-by: Max Reitz <mreitz@redhat.com>
11
11
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
12
12
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
SOURCES/kvm-rtl8139-Do-not-consume-the-packet-during-overflow-in.patch ADDED
@@ -0,0 +1,48 @@
1
+ From 9318bd2b84409c6f3810d410c6918fefec072408 Mon Sep 17 00:00:00 2001
2
+ From: Vlad Yasevich <vyasevic@redhat.com>
3
+ Date: Wed, 16 Dec 2015 02:58:23 +0100
4
+ Subject: [PATCH 6/6] rtl8139: Do not consume the packet during overflow in
5
+ standard mode.
6
+
7
+ Message-id: <1450234703-7606-3-git-send-email-vyasevic@redhat.com>
8
+ Patchwork-id: 68618
9
+ O-Subject: [RHEL7.3 qemu-kvm PATCH 2/2] rtl8139: Do not consume the packet during overflow in standard mode.
10
+ Bugzilla: 1252757
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
+ RH-Acked-by: Xiao Wang <jasowang@redhat.com>
14
+
15
+ When operation in standard mode, we currently return the size
16
+ of packet during buffer overflow. This consumes the overflow
17
+ packet. Return 0 instead so we can re-process the overflow packet
18
+ when we have room.
19
+
20
+ This fixes issues with lost/dropped fragments of large messages.
21
+
22
+ Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
23
+ Reviewed-by: Jason Wang <jasowang@redhat.com>
24
+ Message-id: 1441121206-6997-3-git-send-email-vyasevic@redhat.com
25
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
26
+ (cherry picked from commit 26c4e7ca72d970d120f0f51244bc8d37458512a0)
27
+ Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
28
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
29
+ ---
30
+ hw/net/rtl8139.c | 2 +-
31
+ 1 file changed, 1 insertion(+), 1 deletion(-)
32
+
33
+ diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
34
+ index 6a167df..aa2503d 100644
35
+ --- a/hw/net/rtl8139.c
36
+ +++ b/hw/net/rtl8139.c
37
+ @@ -1148,7 +1148,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
38
+ s->IntrStatus |= RxOverflow;
39
+ ++s->RxMissed;
40
+ rtl8139_update_irq(s);
41
+ - return size_;
42
+ + return 0;
43
+ }
44
+
45
+ packet_header |= RxStatusOK;
46
+ --
47
+ 1.8.3.1
48
+
SOURCES/kvm-rtl8139-Fix-receive-buffer-overflow-check.patch ADDED
@@ -0,0 +1,64 @@
1
+ From dc546cbfdefb8ddbaf121d3b075ca723df264d1c Mon Sep 17 00:00:00 2001
2
+ From: Vlad Yasevich <vyasevic@redhat.com>
3
+ Date: Wed, 16 Dec 2015 02:58:22 +0100
4
+ Subject: [PATCH 5/6] rtl8139: Fix receive buffer overflow check
5
+
6
+ Message-id: <1450234703-7606-2-git-send-email-vyasevic@redhat.com>
7
+ Patchwork-id: 68617
8
+ O-Subject: [RHEL7.3 qemu-kvm PATCH 1/2] rtl8139: Fix receive buffer overflow check
9
+ Bugzilla: 1252757
10
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
11
+ RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
12
+ RH-Acked-by: Xiao Wang <jasowang@redhat.com>
13
+
14
+ rtl8139_do_receive() tries to check for the overflow condition
15
+ by making sure that packet_size + 8 does not exceed the
16
+ available buffer space. The issue here is that RxBuffAddr,
17
+ used to calculate available buffer space, is aligned to a
18
+ a 4 byte boundry after every update. So it is possible that
19
+ every packet ends up being slightly padded when written
20
+ to the receive buffer. This padding is not taken into
21
+ account when checking for overflow and we may end up missing
22
+ the overflow condition can causing buffer overwrite.
23
+
24
+ This patch takes alignment into consideration when
25
+ checking for overflow condition.
26
+
27
+ Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
28
+ Reviewed-by: Jason Wang <jasowang@redhat.com>
29
+ Message-id: 1441121206-6997-2-git-send-email-vyasevic@redhat.com
30
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
31
+ (cherry picked from commit fabdcd3392f16fc666b1d04fc1bbe5f1dbbf10a4)
32
+ Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
33
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
34
+ ---
35
+ hw/net/rtl8139.c | 6 ++++--
36
+ 1 file changed, 4 insertions(+), 2 deletions(-)
37
+
38
+ diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
39
+ index 4f89328..6a167df 100644
40
+ --- a/hw/net/rtl8139.c
41
+ +++ b/hw/net/rtl8139.c
42
+ @@ -1137,7 +1137,9 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
43
+
44
+ /* if receiver buffer is empty then avail == 0 */
45
+
46
+ - if (avail != 0 && size + 8 >= avail)
47
+ +#define RX_ALIGN(x) (((x) + 3) & ~0x3)
48
+ +
49
+ + if (avail != 0 && RX_ALIGN(size + 8) >= avail)
50
+ {
51
+ DPRINTF("rx overflow: rx buffer length %d head 0x%04x "
52
+ "read 0x%04x === available 0x%04x need 0x%04x\n",
53
+ @@ -1165,7 +1167,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
54
+ rtl8139_write_buffer(s, (uint8_t *)&val, 4);
55
+
56
+ /* correct buffer write pointer */
57
+ - s->RxBufAddr = MOD2((s->RxBufAddr + 3) & ~0x3, s->RxBufferSize);
58
+ + s->RxBufAddr = MOD2(RX_ALIGN(s->RxBufAddr), s->RxBufferSize);
59
+
60
+ /* now we can signal we have received something */
61
+
62
+ --
63
+ 1.8.3.1
64
+
SOURCES/kvm-scsi-Advertise-limits-by-blocksize-not-512.patch ADDED
@@ -0,0 +1,54 @@
1
+ From c8644154fb4b460f00c9d24ed9090edc40fef067 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 11 Jul 2016 05:33:39 +0200
4
+ Subject: [PATCH 6/7] scsi: Advertise limits by blocksize, not 512
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1468215219-30793-7-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 71110
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 6/6] scsi: Advertise limits by blocksize, not 512
10
+ Bugzilla: 1318199
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Eric Blake <eblake@redhat.com>
16
+
17
+ s->blocksize may be larger than 512, in which case our
18
+ tweaks to max_xfer_len and opt_xfer_len must be scaled
19
+ appropriately.
20
+
21
+ CC: qemu-stable@nongnu.org
22
+ Reported-by: Fam Zheng <famz@redhat.com>
23
+ Signed-off-by: Eric Blake <eblake@redhat.com>
24
+ Reviewed-by: Fam Zheng <famz@redhat.com>
25
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
+ (cherry picked from commit efaf4781a995aacd22b1dd521b14e4644bafae14)
27
+
28
+ Conflicts:
29
+ hw/scsi/scsi-generic.c
30
+ Downstream uses bdrv_get_max_transfer_length().
31
+
32
+ Signed-off-by: Fam Zheng <famz@redhat.com>
33
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
34
+ ---
35
+ hw/scsi/scsi-generic.c | 3 ++-
36
+ 1 file changed, 2 insertions(+), 1 deletion(-)
37
+
38
+ diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
39
+ index 6b0c1fe..ced92f7 100644
40
+ --- a/hw/scsi/scsi-generic.c
41
+ +++ b/hw/scsi/scsi-generic.c
42
+ @@ -210,7 +210,8 @@ static void scsi_read_complete(void * opaque, int ret)
43
+ } else if (s->type == TYPE_DISK &&
44
+ r->req.cmd.buf[0] == INQUIRY &&
45
+ r->req.cmd.buf[2] == 0xb0) {
46
+ - uint32_t max_xfer_len = bdrv_get_max_transfer_length(s->conf.bs);
47
+ + uint32_t max_xfer_len = bdrv_get_max_transfer_length(s->conf.bs) /
48
+ + (s->blocksize / BDRV_SECTOR_SIZE);
49
+ if (max_xfer_len) {
50
+ stl_be_p(&r->buf[8], max_xfer_len);
51
+ /* Also take care of the opt xfer len. */
52
+ --
53
+ 1.8.3.1
54
+
SOURCES/kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch ADDED
@@ -0,0 +1,67 @@
1
+ From b3f427e4eb27091ca712f6c18e2e63a414dc4ce2 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 11 Jul 2016 05:33:37 +0200
4
+ Subject: [PATCH 4/7] scsi-generic: Merge block max xfer len in INQUIRY
5
+ response
6
+
7
+ RH-Author: Fam Zheng <famz@redhat.com>
8
+ Message-id: <1468215219-30793-5-git-send-email-famz@redhat.com>
9
+ Patchwork-id: 71108
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 4/6] scsi-generic: Merge block max xfer len in INQUIRY response
11
+ Bugzilla: 1318199
12
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13
+ RH-Acked-by: John Snow <jsnow@redhat.com>
14
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
15
+
16
+ The rationale is similar to the above mode sense response interception:
17
+ this is practically the only channel to communicate restraints from
18
+ elsewhere such as host and block driver.
19
+
20
+ The scsi bus we attach onto can have a larger max xfer len than what is
21
+ accepted by the host file system (guarding between the host scsi LUN and
22
+ QEMU), in which case the SG_IO we generate would get -EINVAL.
23
+
24
+ Signed-off-by: Fam Zheng <famz@redhat.com>
25
+ Message-Id: <1464243305-10661-3-git-send-email-famz@redhat.com>
26
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
27
+ (cherry picked from commit 063143d5b1fde0fdcbae30bc7d6d14e76fa607d2)
28
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
29
+
30
+ Conflicts:
31
+ hw/scsi/scsi-generic.c
32
+ We don't have BlockBackend in downstream, use bdrv_get_max_transfer_length()
33
+ instead.
34
+
35
+ The context is different because we don't have fa0d653b0 (scsi-generic:
36
+ identify AIO callbacks more clearly).
37
+
38
+ Signed-off-by: Fam Zheng <famz@redhat.com>
39
+ ---
40
+ hw/scsi/scsi-generic.c | 11 +++++++++++
41
+ 1 file changed, 11 insertions(+)
42
+
43
+ diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
44
+ index 3733d2c..6b0c1fe 100644
45
+ --- a/hw/scsi/scsi-generic.c
46
+ +++ b/hw/scsi/scsi-generic.c
47
+ @@ -207,6 +207,17 @@ static void scsi_read_complete(void * opaque, int ret)
48
+ (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
49
+ s->blocksize = ldl_be_p(&r->buf[8]);
50
+ s->max_lba = ldq_be_p(&r->buf[0]);
51
+ + } else if (s->type == TYPE_DISK &&
52
+ + r->req.cmd.buf[0] == INQUIRY &&
53
+ + r->req.cmd.buf[2] == 0xb0) {
54
+ + uint32_t max_xfer_len = bdrv_get_max_transfer_length(s->conf.bs);
55
+ + if (max_xfer_len) {
56
+ + stl_be_p(&r->buf[8], max_xfer_len);
57
+ + /* Also take care of the opt xfer len. */
58
+ + if (ldl_be_p(&r->buf[12]) > max_xfer_len) {
59
+ + stl_be_p(&r->buf[12], max_xfer_len);
60
+ + }
61
+ + }
62
+ }
63
+ bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
64
+
65
+ --
66
+ 1.8.3.1
67
+
SOURCES/kvm-seccomp-adding-sysinfo-system-call-to-whitelist.patch ADDED
@@ -0,0 +1,48 @@
1
+ From 2dc9b654f678a1cfa95a680f31085cdff1e648b2 Mon Sep 17 00:00:00 2001
2
+ From: Miroslav Rezanina <mrezanin@redhat.com>
3
+ Date: Fri, 22 Apr 2016 05:14:07 +0200
4
+ Subject: [PATCH 02/10] seccomp: adding sysinfo system call to whitelist
5
+
6
+ RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
7
+ Message-id: <1461302047-6677-1-git-send-email-mrezanin@redhat.com>
8
+ Patchwork-id: 70221
9
+ O-Subject: [RHEL 7.3 qemu-kvm PATCH] seccomp: adding sysinfo system call to whitelist
10
+ Bugzilla: 1177318
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
13
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
14
+
15
+ From: Miroslav Rezanina <mrezanin@redhat.com>
16
+
17
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1177318
18
+ Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=10914613
19
+ RHEV: BZ 1177309, fixed with 2.6 rebase
20
+
21
+ Newer version of nss-softokn libraries (> 3.16.2.3) use sysinfo call
22
+ so qemu using rbd image hang after start when run in sandbox mode.
23
+
24
+ To allow using rbd images in sandbox mode we have to whitelist it.
25
+
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+ Acked-by: Eduardo Otubo <eduardo.otubo@profitbricks.com>
28
+ (cherry picked from commit 8e08f8a4a7f613af65b29fcc3ac3bfc2a08a3343)
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ qemu-seccomp.c | 1 +
32
+ 1 file changed, 1 insertion(+)
33
+
34
+ diff --git a/qemu-seccomp.c b/qemu-seccomp.c
35
+ index 5e60fce..e947909 100644
36
+ --- a/qemu-seccomp.c
37
+ +++ b/qemu-seccomp.c
38
+ @@ -249,6 +249,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
39
+ { SCMP_SYS(munlock), 240 },
40
+ { SCMP_SYS(semctl), 240 },
41
+ { SCMP_SYS(timerfd_create), 240 },
42
+ + { SCMP_SYS(sysinfo), 240 },
43
+ };
44
+
45
+ int seccomp_start(void)
46
+ --
47
+ 1.8.3.1
48
+
SOURCES/kvm-spice-do-not-require-TCP-ports.patch ADDED
@@ -0,0 +1,48 @@
1
+ From f40c437eed664b31984a21ec6bbed12c6b03dd0b Mon Sep 17 00:00:00 2001
2
+ From: Gerd Hoffmann <kraxel@redhat.com>
3
+ Date: Wed, 1 Jun 2016 13:16:08 +0200
4
+ Subject: [PATCH 1/2] spice: do not require TCP ports
5
+ MIME-Version: 1.0
6
+ Content-Type: text/plain; charset=UTF-8
7
+ Content-Transfer-Encoding: 8bit
8
+
9
+ RH-Author: Gerd Hoffmann <kraxel@redhat.com>
10
+ Message-id: <1464786968-25518-2-git-send-email-kraxel@redhat.com>
11
+ Patchwork-id: 70523
12
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] spice: do not require TCP ports
13
+ Bugzilla: 1336491
14
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
15
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
16
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
17
+
18
+ From: Marc-André Lureau <marcandre.lureau@gmail.com>
19
+
20
+ It is possible to use Spice server without TCP port. On local VM,
21
+ qemu (and libvirt) can add new clients thanks to QMP add_client command.
22
+
23
+ Signed-off-by: Marc-André Lureau <marcandre.lureau@gmail.com>
24
+ Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
25
+ (cherry picked from commit cf7856adefebe86e0cd50302d93b3045e3111690)
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+ ---
28
+ ui/spice-core.c | 4 ----
29
+ 1 file changed, 4 deletions(-)
30
+
31
+ diff --git a/ui/spice-core.c b/ui/spice-core.c
32
+ index 141afd1..8d6e726 100644
33
+ --- a/ui/spice-core.c
34
+ +++ b/ui/spice-core.c
35
+ @@ -648,10 +648,6 @@ void qemu_spice_init(void)
36
+ }
37
+ port = qemu_opt_get_number(opts, "port", 0);
38
+ tls_port = qemu_opt_get_number(opts, "tls-port", 0);
39
+ - if (!port && !tls_port) {
40
+ - error_report("neither port nor tls-port specified for spice");
41
+ - exit(1);
42
+ - }
43
+ if (port < 0 || port > 65535) {
44
+ error_report("spice port is out of range");
45
+ exit(1);
46
+ --
47
+ 1.8.3.1
48
+
SOURCES/kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch ADDED
@@ -0,0 +1,93 @@
1
+ From 73b0c0b62c08330e65e9ec3d54ae5738d4b5211d Mon Sep 17 00:00:00 2001
2
+ From: Eduardo Habkost <ehabkost@redhat.com>
3
+ Date: Fri, 9 Sep 2016 19:08:34 +0200
4
+ Subject: [PATCH 2/2] target-i386: Add more Intel AVX-512 instructions support
5
+
6
+ RH-Author: Eduardo Habkost <ehabkost@redhat.com>
7
+ Message-id: <1473448114-1430-3-git-send-email-ehabkost@redhat.com>
8
+ Patchwork-id: 72277
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/2] target-i386: Add more Intel AVX-512 instructions support
10
+ Bugzilla: 1372459
11
+ RH-Acked-by: Bandan Das <bsd@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Luwei Kang <luwei.kang@intel.com>
16
+
17
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1372459
18
+
19
+ Add more AVX512 feature bits, include AVX512DQ, AVX512IFMA,
20
+ AVX512BW, AVX512VL, AVX512VBMI. Its spec can be found at:
21
+ https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
22
+
23
+ Signed-off-by: Luwei Kang <luwei.kang@intel.com>
24
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
25
+ (cherry picked from commit cc728d1493eee3e20c1547191862e43d3f55e714)
26
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+ ---
29
+ target-i386/cpu.c | 14 +++++++++-----
30
+ target-i386/cpu.h | 13 +++++++++++++
31
+ 2 files changed, 22 insertions(+), 5 deletions(-)
32
+
33
+ diff --git a/target-i386/cpu.c b/target-i386/cpu.c
34
+ index d9c214c..476306d 100644
35
+ --- a/target-i386/cpu.c
36
+ +++ b/target-i386/cpu.c
37
+ @@ -144,14 +144,18 @@ static const char *svm_feature_name[] = {
38
+ };
39
+
40
+ static const char *cpuid_7_0_ebx_feature_name[] = {
41
+ - "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
42
+ - "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL,
43
+ - "avx512f", NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
44
+ - NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
45
+ + "fsgsbase", NULL, NULL, "bmi1",
46
+ + "hle", "avx2", NULL, "smep",
47
+ + "bmi2", "erms", "invpcid", "rtm",
48
+ + NULL, NULL, "mpx", NULL,
49
+ + "avx512f", "avx512dq", "rdseed", "adx",
50
+ + "smap", "avx512ifma", NULL, NULL,
51
+ + NULL, NULL, "avx512pf", "avx512er",
52
+ + "avx512cd", NULL, "avx512bw", "avx512vl",
53
+ };
54
+
55
+ static const char *cpuid_7_0_ecx_feature_name[] = {
56
+ - NULL, NULL, NULL, NULL,
57
+ + NULL, "avx512vbmi", NULL, NULL,
58
+ NULL, NULL, NULL, NULL,
59
+ NULL, NULL, NULL, NULL,
60
+ NULL, NULL, NULL, NULL,
61
+ diff --git a/target-i386/cpu.h b/target-i386/cpu.h
62
+ index 5c62ee3..d541809 100644
63
+ --- a/target-i386/cpu.h
64
+ +++ b/target-i386/cpu.h
65
+ @@ -560,12 +560,25 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
66
+ #define CPUID_7_0_EBX_RTM (1U << 11)
67
+ #define CPUID_7_0_EBX_MPX (1U << 14)
68
+ #define CPUID_7_0_EBX_AVX512F (1U << 16) /* AVX-512 Foundation */
69
+ +#define CPUID_7_0_EBX_AVX512DQ (1U << 17) /* AVX-512 Doubleword & Quadword Instrs */
70
+ #define CPUID_7_0_EBX_RDSEED (1U << 18)
71
+ #define CPUID_7_0_EBX_ADX (1U << 19)
72
+ #define CPUID_7_0_EBX_SMAP (1U << 20)
73
+ +#define CPUID_7_0_EBX_AVX512IFMA (1U << 21) /* AVX-512 Integer Fused Multiply Add */
74
+ +#define CPUID_7_0_EBX_PCOMMIT (1U << 22) /* Persistent Commit */
75
+ +#define CPUID_7_0_EBX_CLFLUSHOPT (1U << 23) /* Flush a Cache Line Optimized */
76
+ +#define CPUID_7_0_EBX_CLWB (1U << 24) /* Cache Line Write Back */
77
+ #define CPUID_7_0_EBX_AVX512PF (1U << 26) /* AVX-512 Prefetch */
78
+ #define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */
79
+ #define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */
80
+ +#define CPUID_7_0_EBX_AVX512BW (1U << 30) /* AVX-512 Byte and Word Instructions */
81
+ +#define CPUID_7_0_EBX_AVX512VL (1U << 31) /* AVX-512 Vector Length Extensions */
82
+ +
83
+ +#define CPUID_7_0_ECX_VBMI (1U << 1) /* AVX-512 Vector Byte Manipulation Instrs */
84
+ +#define CPUID_7_0_ECX_UMIP (1U << 2)
85
+ +#define CPUID_7_0_ECX_PKU (1U << 3)
86
+ +#define CPUID_7_0_ECX_OSPKE (1U << 4)
87
+ +#define CPUID_7_0_ECX_RDPID (1U << 22)
88
+
89
+ #define CPUID_XSAVE_XSAVEOPT (1U << 0)
90
+ #define CPUID_XSAVE_XSAVEC (1U << 1)
91
+ --
92
+ 1.8.3.1
93
+
SOURCES/kvm-target-i386-Add-support-for-FEAT_7_0_ECX.patch ADDED
@@ -0,0 +1,147 @@
1
+ From eb87f1106d038247356ecd3071e6fa5654386ff5 Mon Sep 17 00:00:00 2001
2
+ From: Eduardo Habkost <ehabkost@redhat.com>
3
+ Date: Fri, 9 Sep 2016 19:08:33 +0200
4
+ Subject: [PATCH 1/2] target-i386: Add support for FEAT_7_0_ECX
5
+
6
+ RH-Author: Eduardo Habkost <ehabkost@redhat.com>
7
+ Message-id: <1473448114-1430-2-git-send-email-ehabkost@redhat.com>
8
+ Patchwork-id: 72276
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/2] target-i386: Add support for FEAT_7_0_ECX
10
+ Bugzilla: 1372459
11
+ RH-Acked-by: Bandan Das <bsd@redhat.com>
12
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Paolo Bonzini <pbonzini@redhat.com>
16
+
17
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1372459
18
+
19
+ Done from scratch by copying what is done for FEAT_7_0_EBX. Compare
20
+ to upstream commit f74eefe ("target-i386: Add PKU and and OSPKE support",
21
+ 2016-01-21), but without actually adding PKU and OSPKE. Because all
22
+ these features are "-cpu host"-only, they can be added without modifying
23
+ machine types.
24
+
25
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
26
+ [ehabkost: v2: removed the non-upstream cpuid_level < 7 check]
27
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
28
+
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ target-i386/cpu.c | 29 ++++++++++++++++++++++++++++-
32
+ target-i386/cpu.h | 1 +
33
+ 2 files changed, 29 insertions(+), 1 deletion(-)
34
+
35
+ diff --git a/target-i386/cpu.c b/target-i386/cpu.c
36
+ index 1001c47..d9c214c 100644
37
+ --- a/target-i386/cpu.c
38
+ +++ b/target-i386/cpu.c
39
+ @@ -150,6 +150,17 @@ static const char *cpuid_7_0_ebx_feature_name[] = {
40
+ NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
41
+ };
42
+
43
+ +static const char *cpuid_7_0_ecx_feature_name[] = {
44
+ + NULL, NULL, NULL, NULL,
45
+ + NULL, NULL, NULL, NULL,
46
+ + NULL, NULL, NULL, NULL,
47
+ + NULL, NULL, NULL, NULL,
48
+ + NULL, NULL, NULL, NULL,
49
+ + NULL, NULL, NULL, NULL,
50
+ + NULL, NULL, NULL, NULL,
51
+ + NULL, NULL, NULL, NULL,
52
+ +};
53
+ +
54
+ static const char *cpuid_xsave_feature_name[] = {
55
+ "xsaveopt", "xsavec", "xgetbv1", NULL,
56
+ NULL, NULL, NULL, NULL,
57
+ @@ -204,6 +215,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
58
+ .cpuid_needs_ecx = true, .cpuid_ecx = 0,
59
+ .cpuid_reg = R_EBX,
60
+ },
61
+ + [FEAT_7_0_ECX] = {
62
+ + .feat_names = cpuid_7_0_ecx_feature_name,
63
+ + .cpuid_eax = 7,
64
+ + .cpuid_needs_ecx = true, .cpuid_ecx = 0,
65
+ + .cpuid_reg = R_ECX,
66
+ + },
67
+ [FEAT_XSAVE] = {
68
+ .feat_names = cpuid_xsave_feature_name,
69
+ .cpuid_eax = 0xd,
70
+ @@ -462,6 +479,7 @@ typedef struct x86_def_t {
71
+ CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
72
+ CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
73
+ CPUID_7_0_EBX_RDSEED */
74
+ +#define TCG_7_0_ECX_FEATURES 0
75
+
76
+ /* built-in CPU model definitions
77
+ */
78
+ @@ -1198,8 +1216,11 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
79
+ if (x86_cpu_def->level >= 7) {
80
+ x86_cpu_def->features[FEAT_7_0_EBX] =
81
+ kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
82
+ + x86_cpu_def->features[FEAT_7_0_ECX] =
83
+ + kvm_arch_get_supported_cpuid(s, 0x7, 0, R_ECX);
84
+ } else {
85
+ x86_cpu_def->features[FEAT_7_0_EBX] = 0;
86
+ + x86_cpu_def->features[FEAT_7_0_ECX] = 0;
87
+ }
88
+ x86_cpu_def->features[FEAT_XSAVE] =
89
+ kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
90
+ @@ -1283,6 +1304,9 @@ static int kvm_check_features_against_host(X86CPU *cpu)
91
+ {&env->features[FEAT_7_0_EBX],
92
+ &host_def.features[FEAT_7_0_EBX],
93
+ FEAT_7_0_EBX },
94
+ + {&env->features[FEAT_7_0_ECX],
95
+ + &host_def.features[FEAT_7_0_ECX],
96
+ + FEAT_7_0_ECX },
97
+ {&env->features[FEAT_XSAVE],
98
+ &host_def.features[FEAT_XSAVE],
99
+ FEAT_XSAVE },
100
+ @@ -1824,6 +1848,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
101
+ env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
102
+ env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
103
+ env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
104
+ + env->features[FEAT_7_0_ECX] |= plus_features[FEAT_7_0_ECX];
105
+ env->features[FEAT_XSAVE] |= plus_features[FEAT_XSAVE];
106
+ env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
107
+ env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
108
+ @@ -1833,6 +1858,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
109
+ env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
110
+ env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
111
+ env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
112
+ + env->features[FEAT_7_0_ECX] &= ~minus_features[FEAT_7_0_ECX];
113
+ env->features[FEAT_XSAVE] &= ~minus_features[FEAT_XSAVE];
114
+
115
+ out:
116
+ @@ -1969,6 +1995,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
117
+ env->features[FEAT_SVM] = def->features[FEAT_SVM];
118
+ env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
119
+ env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
120
+ + env->features[FEAT_7_0_ECX] = def->features[FEAT_7_0_ECX];
121
+ env->features[FEAT_XSAVE] = def->features[FEAT_XSAVE];
122
+ env->cpuid_xlevel2 = def->xlevel2;
123
+
124
+ @@ -2206,7 +2233,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
125
+ if (count == 0) {
126
+ *eax = 0; /* Maximum ECX value for sub-leaves */
127
+ *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
128
+ - *ecx = 0; /* Reserved */
129
+ + *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
130
+ *edx = 0; /* Reserved */
131
+ } else {
132
+ *eax = 0;
133
+ diff --git a/target-i386/cpu.h b/target-i386/cpu.h
134
+ index da7e060..5c62ee3 100644
135
+ --- a/target-i386/cpu.h
136
+ +++ b/target-i386/cpu.h
137
+ @@ -400,6 +400,7 @@ typedef enum FeatureWord {
138
+ FEAT_1_EDX, /* CPUID[1].EDX */
139
+ FEAT_1_ECX, /* CPUID[1].ECX */
140
+ FEAT_7_0_EBX, /* CPUID[EAX=7,ECX=0].EBX */
141
+ + FEAT_7_0_ECX, /* CPUID[EAX=7,ECX=0].ECX */
142
+ FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
143
+ FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
144
+ FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
145
+ --
146
+ 1.8.3.1
147
+
SOURCES/kvm-target-i386-add-Skylake-Client-cpu-model.patch ADDED
@@ -0,0 +1,92 @@
1
+ From ce561d78c7199821beae26112f41da5733fab5bb Mon Sep 17 00:00:00 2001
2
+ From: Eduardo Habkost <ehabkost@redhat.com>
3
+ Date: Wed, 6 Jul 2016 20:47:53 +0200
4
+ Subject: [PATCH 2/2] target-i386: add Skylake-Client cpu model
5
+
6
+ RH-Author: Eduardo Habkost <ehabkost@redhat.com>
7
+ Message-id: <1467838073-23873-3-git-send-email-ehabkost@redhat.com>
8
+ Patchwork-id: 71052
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 2/2] target-i386: add Skylake-Client cpu model
10
+ Bugzilla: 1327599
11
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
12
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
13
+ RH-Acked-by: Bandan Das <bsd@redhat.com>
14
+
15
+ Introduce Skylake-Client cpu mode which inherits the features from
16
+ Broadwell and supports some additional features that are: MPX,
17
+ XSAVEC, and XGETBV1.
18
+
19
+ Backport notes:
20
+ * ARAT feature not included, as it is not available in the
21
+ qemu-kvm-1.5.3 tree (and disabled by compat code in
22
+ pc-i440fx-rhel7.2.0 and older on qemu-kvm-rhev)
23
+
24
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
25
+ Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
26
+ Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
27
+ Reviewed-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
28
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
29
+ (cherry picked from commit f6f949e9295889fb272698aea763dcea77d616ce)
30
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
31
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
32
+ ---
33
+ target-i386/cpu.c | 43 +++++++++++++++++++++++++++++++++++++++++++
34
+ 1 file changed, 43 insertions(+)
35
+
36
+ diff --git a/target-i386/cpu.c b/target-i386/cpu.c
37
+ index 6650c72..80106ba 100644
38
+ --- a/target-i386/cpu.c
39
+ +++ b/target-i386/cpu.c
40
+ @@ -927,6 +927,49 @@ static x86_def_t builtin_x86_defs[] = {
41
+ .model_id = "Intel Core Processor (Broadwell)",
42
+ },
43
+ {
44
+ + .name = "Skylake-Client",
45
+ + .level = 0xd,
46
+ + .vendor = CPUID_VENDOR_INTEL,
47
+ + .family = 6,
48
+ + .model = 94,
49
+ + .stepping = 3,
50
+ + .features[FEAT_1_EDX] =
51
+ + CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
52
+ + CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
53
+ + CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
54
+ + CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
55
+ + CPUID_DE | CPUID_FP87,
56
+ + .features[FEAT_1_ECX] =
57
+ + CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
58
+ + CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
59
+ + CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
60
+ + CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
61
+ + CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
62
+ + CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
63
+ + .features[FEAT_8000_0001_EDX] =
64
+ + CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
65
+ + CPUID_EXT2_SYSCALL,
66
+ + .features[FEAT_8000_0001_ECX] =
67
+ + CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
68
+ + .features[FEAT_7_0_EBX] =
69
+ + CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
70
+ + CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
71
+ + CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
72
+ + CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
73
+ + CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
74
+ + /* Missing: XSAVES (not supported by some Linux versions,
75
+ + * including v4.1 to v4.6).
76
+ + * KVM doesn't yet expose any XSAVES state save component,
77
+ + * and the only one defined in Skylake (processor tracing)
78
+ + * probably will block migration anyway.
79
+ + */
80
+ + .features[FEAT_XSAVE] =
81
+ + CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
82
+ + CPUID_XSAVE_XGETBV1,
83
+ + .xlevel = 0x80000008,
84
+ + .model_id = "Intel Core Processor (Skylake)",
85
+ + },
86
+ + {
87
+ .name = "Opteron_G1",
88
+ .level = 5,
89
+ .vendor = CPUID_VENDOR_AMD,
90
+ --
91
+ 1.8.3.1
92
+
SOURCES/kvm-target-i386-add-feature-flags-for-CPUID-EAX-0xd-ECX-.patch ADDED
@@ -0,0 +1,168 @@
1
+ From 5fcaf5176d7545518c76f3aa8ea7ce6fb063c62d Mon Sep 17 00:00:00 2001
2
+ From: Eduardo Habkost <ehabkost@redhat.com>
3
+ Date: Wed, 6 Jul 2016 20:47:52 +0200
4
+ Subject: [PATCH 1/2] target-i386: add feature flags for CPUID[EAX=0xd, ECX=1]
5
+
6
+ RH-Author: Eduardo Habkost <ehabkost@redhat.com>
7
+ Message-id: <1467838073-23873-2-git-send-email-ehabkost@redhat.com>
8
+ Patchwork-id: 71051
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/2] target-i386: add feature flags for CPUID[EAX=0xd, ECX=1]
10
+ Bugzilla: 1327599
11
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
12
+ RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
13
+ RH-Acked-by: Bandan Das <bsd@redhat.com>
14
+
15
+ From: Paolo Bonzini <pbonzini@redhat.com>
16
+
17
+ These represent xsave-related capabilities of the processor, and KVM may
18
+ or may not support them.
19
+
20
+ Add feature bits so that they are considered by "-cpu ...,enforce", and use
21
+ the new feature work instead of calling kvm_arch_get_supported_cpuid.
22
+
23
+ Bit 3 (XSAVES) is not migratables because it requires saving MSR_IA32_XSS.
24
+ Neither KVM nor any commonly available hardware supports it anyway.
25
+
26
+ RHEL backport notes:
27
+ * In addition to allowing xsave flags to be configured, this
28
+ patch is a bug fix because we shouldn't use
29
+ kvm_arch_supported_cpuid() directly when configuring CPUID for
30
+ the guest
31
+ * tcg_features didn't exist, handle it inside x86_cpu_realizefn()
32
+ directly in the !kvm_enabled() check
33
+ * As the unmigratable_flags mechanism is not present yet,
34
+ remove the "xsaves" flag name so it can't be enabled manually
35
+ (otherwise we would need to backport upstream commit
36
+ 18cd2c17b5370369a886155c001da0a7f54bbcca too)
37
+
38
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
39
+ (cherry picked from commit 0bb0b2d2fe7f645ddaf1f0ff40ac669c9feb4aa1)
40
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
41
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
42
+ ---
43
+ target-i386/cpu.c | 28 +++++++++++++++++++++++++++-
44
+ target-i386/cpu.h | 6 ++++++
45
+ 2 files changed, 33 insertions(+), 1 deletion(-)
46
+
47
+ diff --git a/target-i386/cpu.c b/target-i386/cpu.c
48
+ index 06efe17..6650c72 100644
49
+ --- a/target-i386/cpu.c
50
+ +++ b/target-i386/cpu.c
51
+ @@ -150,6 +150,17 @@ static const char *cpuid_7_0_ebx_feature_name[] = {
52
+ NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
53
+ };
54
+
55
+ +static const char *cpuid_xsave_feature_name[] = {
56
+ + "xsaveopt", "xsavec", "xgetbv1", NULL,
57
+ + NULL, NULL, NULL, NULL,
58
+ + NULL, NULL, NULL, NULL,
59
+ + NULL, NULL, NULL, NULL,
60
+ + NULL, NULL, NULL, NULL,
61
+ + NULL, NULL, NULL, NULL,
62
+ + NULL, NULL, NULL, NULL,
63
+ + NULL, NULL, NULL, NULL,
64
+ +};
65
+ +
66
+ typedef struct FeatureWordInfo {
67
+ const char **feat_names;
68
+ uint32_t cpuid_eax; /* Input EAX for CPUID */
69
+ @@ -193,6 +204,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
70
+ .cpuid_needs_ecx = true, .cpuid_ecx = 0,
71
+ .cpuid_reg = R_EBX,
72
+ },
73
+ + [FEAT_XSAVE] = {
74
+ + .feat_names = cpuid_xsave_feature_name,
75
+ + .cpuid_eax = 0xd,
76
+ + .cpuid_needs_ecx = true, .cpuid_ecx = 1,
77
+ + .cpuid_reg = R_EAX,
78
+ + },
79
+ };
80
+
81
+ typedef struct X86RegisterInfo32 {
82
+ @@ -833,6 +850,8 @@ static x86_def_t builtin_x86_defs[] = {
83
+ CPUID_EXT2_SYSCALL,
84
+ .features[FEAT_8000_0001_ECX] =
85
+ CPUID_EXT3_LAHF_LM,
86
+ + .features[FEAT_XSAVE] =
87
+ + CPUID_XSAVE_XSAVEOPT,
88
+ .xlevel = 0x8000000A,
89
+ .model_id = "Intel Xeon E312xx (Sandy Bridge)",
90
+ },
91
+ @@ -866,6 +885,8 @@ static x86_def_t builtin_x86_defs[] = {
92
+ CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
93
+ CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
94
+ CPUID_7_0_EBX_RTM,
95
+ + .features[FEAT_XSAVE] =
96
+ + CPUID_XSAVE_XSAVEOPT,
97
+ .xlevel = 0x8000000A,
98
+ .model_id = "Intel Core Processor (Haswell)",
99
+ },
100
+ @@ -900,6 +921,8 @@ static x86_def_t builtin_x86_defs[] = {
101
+ CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
102
+ CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
103
+ CPUID_7_0_EBX_SMAP,
104
+ + .features[FEAT_XSAVE] =
105
+ + CPUID_XSAVE_XSAVEOPT,
106
+ .xlevel = 0x8000000A,
107
+ .model_id = "Intel Core Processor (Broadwell)",
108
+ },
109
+ @@ -1017,6 +1040,7 @@ static x86_def_t builtin_x86_defs[] = {
110
+ CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
111
+ CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
112
+ CPUID_EXT3_LAHF_LM,
113
+ + /* no xsaveopt! */
114
+ .xlevel = 0x8000001A,
115
+ .model_id = "AMD Opteron 62xx class CPU",
116
+ },
117
+ @@ -1051,6 +1075,7 @@ static x86_def_t builtin_x86_defs[] = {
118
+ CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
119
+ CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
120
+ CPUID_EXT3_LAHF_LM,
121
+ + /* no xsaveopt! */
122
+ .xlevel = 0x8000001A,
123
+ .model_id = "AMD Opteron 63xx class CPU",
124
+ },
125
+ @@ -2196,7 +2221,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
126
+ *eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
127
+ *ebx = *ecx;
128
+ } else if (count == 1) {
129
+ - *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
130
+ + *eax = env->features[FEAT_XSAVE];
131
+ } else if (count < ARRAY_SIZE(ext_save_areas)) {
132
+ const ExtSaveArea *esa = &ext_save_areas[count];
133
+ if ((env->features[esa->feature] & esa->bits) == esa->bits &&
134
+ @@ -2540,6 +2565,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
135
+ );
136
+ env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
137
+ env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
138
+ + env->features[FEAT_XSAVE] = 0;
139
+ } else {
140
+ if ((cpu->check_cpuid || cpu->enforce_cpuid)
141
+ && kvm_check_features_against_host(cpu) && cpu->enforce_cpuid) {
142
+ diff --git a/target-i386/cpu.h b/target-i386/cpu.h
143
+ index 61e9b86..da7e060 100644
144
+ --- a/target-i386/cpu.h
145
+ +++ b/target-i386/cpu.h
146
+ @@ -405,6 +405,7 @@ typedef enum FeatureWord {
147
+ FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
148
+ FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
149
+ FEAT_SVM, /* CPUID[8000_000A].EDX */
150
+ + FEAT_XSAVE, /* CPUID[EAX=0xd,ECX=1].EAX */
151
+ FEATURE_WORDS,
152
+ } FeatureWord;
153
+
154
+ @@ -565,6 +566,11 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
155
+ #define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */
156
+ #define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */
157
+
158
+ +#define CPUID_XSAVE_XSAVEOPT (1U << 0)
159
+ +#define CPUID_XSAVE_XSAVEC (1U << 1)
160
+ +#define CPUID_XSAVE_XGETBV1 (1U << 2)
161
+ +#define CPUID_XSAVE_XSAVES (1U << 3)
162
+ +
163
+ #define CPUID_VENDOR_SZ 12
164
+
165
+ #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
166
+ --
167
+ 1.8.3.1
168
+
SOURCES/kvm-target-i386-fix-pcmpxstrx-equal-ordered-strstr-mode.patch ADDED
@@ -0,0 +1,57 @@
1
+ From b05eb2cc7decc07ed044484861587b3490144d02 Mon Sep 17 00:00:00 2001
2
+ From: Paolo Bonzini <pbonzini@redhat.com>
3
+ Date: Wed, 8 Jun 2016 13:04:21 +0200
4
+ Subject: [PATCH 2/3] target-i386: fix pcmpxstrx equal-ordered (strstr) mode
5
+
6
+ RH-Author: Paolo Bonzini <pbonzini@redhat.com>
7
+ Message-id: <1465391061-17748-1-git-send-email-pbonzini@redhat.com>
8
+ Patchwork-id: 70570
9
+ O-Subject: [RHEL7.3/7.2.z qemu-kvm PATCH] target-i386: fix pcmpxstrx equal-ordered (strstr) mode
10
+ Bugzilla: 1340971
11
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
13
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
14
+
15
+ Kindly requested by the Openstack folks, who sometimes uses TCG
16
+ instead of nested virt.
17
+
18
+ In this mode, referring an invalid element of the source forces the
19
+ result to false (table 4-7, last column) but referring an invalid
20
+ element of the destination forces the result to true, so the outer
21
+ loop should still be run even if some elements of the destination
22
+ will be invalid. They will be avoided in the inner loop, which
23
+ correctly bounds "i" to validd, but they will still contribute to a
24
+ positive outcome of the search.
25
+
26
+ This fixes tst_strstr in glibc 2.17.
27
+
28
+ Reported-by: Florian Weimer <fweimer@redhat.com>
29
+ Cc: Richard Henderson <rth@twiddle.net>
30
+ Cc: Eduardo Habkost <ehabkost@redhat.com>
31
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
32
+ (cherry picked from commit 54c54f8b56047d3c2420e1ae06a6a8890c220ac4)
33
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
34
+ ---
35
+ target-i386/ops_sse.h | 4 ++--
36
+ 1 file changed, 2 insertions(+), 2 deletions(-)
37
+
38
+ diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
39
+ index eb24b5f..5145d9e 100644
40
+ --- a/target-i386/ops_sse.h
41
+ +++ b/target-i386/ops_sse.h
42
+ @@ -2034,10 +2034,10 @@ static inline unsigned pcmpxstrx(CPUX86State *env, Reg *d, Reg *s,
43
+ }
44
+ break;
45
+ case 3:
46
+ - for (j = valids - validd; j >= 0; j--) {
47
+ + for (j = valids; j >= 0; j--) {
48
+ res <<= 1;
49
+ v = 1;
50
+ - for (i = MIN(upper - j, validd); i >= 0; i--) {
51
+ + for (i = MIN(valids - j, validd); i >= 0; i--) {
52
+ v &= (pcmp_val(s, ctrl, i + j) == pcmp_val(d, ctrl, i));
53
+ }
54
+ res |= v;
55
+ --
56
+ 1.8.3.1
57
+
SOURCES/kvm-target-i386-get-put-MSR_TSC_AUX-across-reset-and-mig.patch ADDED
@@ -0,0 +1,93 @@
1
+ From f9a24822687113e34194f05aeb641365b8202e9e Mon Sep 17 00:00:00 2001
2
+ From: Amit Shah <amit.shah@redhat.com>
3
+ Date: Wed, 25 Nov 2015 05:51:34 +0100
4
+ Subject: [PATCH 4/6] target-i386: get/put MSR_TSC_AUX across reset and
5
+ migration
6
+
7
+ Message-id: <daab7f1c955ec81df8aff4ab10fd6ae17e16e99e.1448430513.git.amit.shah@redhat.com>
8
+ Patchwork-id: 68467
9
+ O-Subject: [RHEL 7.3 qemu-kvm PATCH 1/1] target-i386: get/put MSR_TSC_AUX across reset and migration
10
+ Bugzilla: 1265427
11
+ RH-Acked-by: Juan Quintela <quintela@redhat.com>
12
+ RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ There's one report of migration breaking due to missing MSR_TSC_AUX
16
+ save/restore. Fix this by adding a new subsection that saves the state
17
+ of this MSR.
18
+
19
+ https://bugzilla.redhat.com/show_bug.cgi?id=1261797
20
+
21
+ Reported-by: Xiaoqing Wei <xwei@redhat.com>
22
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
23
+ CC: Paolo Bonzini <pbonzini@redhat.com>
24
+ CC: Juan Quintela <quintela@redhat.com>
25
+ CC: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
26
+ CC: Marcelo Tosatti <mtosatti@redhat.com>
27
+ CC: Richard Henderson <rth@twiddle.net>
28
+ CC: Eduardo Habkost <ehabkost@redhat.com>
29
+ Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
30
+ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
31
+ (cherry picked from commit c9b8f6b6210847b4381c5b2ee172b1c7eb9985d6)
32
+ Signed-off-by: Amit Shah <amit.shah@redhat.com>
33
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
34
+ ---
35
+ target-i386/kvm.c | 14 ++++++++++++++
36
+ 1 file changed, 14 insertions(+)
37
+
38
+ diff --git a/target-i386/kvm.c b/target-i386/kvm.c
39
+ index c91bfb8..e1b0ca2 100644
40
+ --- a/target-i386/kvm.c
41
+ +++ b/target-i386/kvm.c
42
+ @@ -63,6 +63,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
43
+
44
+ static bool has_msr_star;
45
+ static bool has_msr_hsave_pa;
46
+ +static bool has_msr_tsc_aux;
47
+ static bool has_msr_tsc_adjust;
48
+ static bool has_msr_tsc_deadline;
49
+ static bool has_msr_async_pf_en;
50
+ @@ -774,6 +775,10 @@ static int kvm_get_supported_msrs(KVMState *s)
51
+ has_msr_hsave_pa = true;
52
+ continue;
53
+ }
54
+ + if (kvm_msr_list->indices[i] == MSR_TSC_AUX) {
55
+ + has_msr_tsc_aux = true;
56
+ + continue;
57
+ + }
58
+ if (kvm_msr_list->indices[i] == MSR_TSC_ADJUST) {
59
+ has_msr_tsc_adjust = true;
60
+ continue;
61
+ @@ -1159,6 +1164,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
62
+ if (has_msr_hsave_pa) {
63
+ kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
64
+ }
65
+ + if (has_msr_tsc_aux) {
66
+ + kvm_msr_entry_set(&msrs[n++], MSR_TSC_AUX, env->tsc_aux);
67
+ + }
68
+ if (has_msr_tsc_adjust) {
69
+ kvm_msr_entry_set(&msrs[n++], MSR_TSC_ADJUST, env->tsc_adjust);
70
+ }
71
+ @@ -1507,6 +1515,9 @@ static int kvm_get_msrs(X86CPU *cpu)
72
+ if (has_msr_hsave_pa) {
73
+ msrs[n++].index = MSR_VM_HSAVE_PA;
74
+ }
75
+ + if (has_msr_tsc_aux) {
76
+ + msrs[n++].index = MSR_TSC_AUX;
77
+ + }
78
+ if (has_msr_tsc_adjust) {
79
+ msrs[n++].index = MSR_TSC_ADJUST;
80
+ }
81
+ @@ -1636,6 +1647,9 @@ static int kvm_get_msrs(X86CPU *cpu)
82
+ case MSR_IA32_TSC:
83
+ env->tsc = msrs[i].data;
84
+ break;
85
+ + case MSR_TSC_AUX:
86
+ + env->tsc_aux = msrs[i].data;
87
+ + break;
88
+ case MSR_TSC_ADJUST:
89
+ env->tsc_adjust = msrs[i].data;
90
+ break;
91
+ --
92
+ 1.8.3.1
93
+
SOURCES/kvm-trace-remove-malloc-tracing.patch ADDED
@@ -0,0 +1,104 @@
1
+ From d15566b6a91973dbf83c92a9678bd3ac4939af75 Mon Sep 17 00:00:00 2001
2
+ From: Miroslav Rezanina <mrezanin@redhat.com>
3
+ Date: Fri, 29 Jul 2016 07:41:27 +0200
4
+ Subject: [PATCH 16/16] trace: remove malloc tracing
5
+
6
+ RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
7
+ Message-id: <1469778087-316-1-git-send-email-mrezanin@redhat.com>
8
+ Patchwork-id: 71514
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH] trace: remove malloc tracing
10
+ Bugzilla: 1360137
11
+ RH-Acked-by: Fam Zheng <famz@redhat.com>
12
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
13
+ RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
14
+ RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
15
+
16
+ From: Paolo Bonzini <pbonzini@redhat.com>
17
+
18
+ The malloc vtable is not supported anymore in glib, because it broke
19
+ when constructors called g_malloc. Remove tracing of g_malloc,
20
+ g_realloc and g_free calls.
21
+
22
+ Note that, for systemtap users, glib also provides tracepoints
23
+ glib.mem_alloc, glib.mem_free, glib.mem_realloc, glib.slice_alloc
24
+ and glib.slice_free.
25
+
26
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
27
+ Reviewed-by: Alberto Garcia <berto@igalia.com>
28
+ Message-id: 1442417924-25831-1-git-send-email-pbonzini@redhat.com
29
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
30
+ (cherry picked from commit 98cf48f60aa4999f5b2808569a193a401a390e6a)
31
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
32
+ ---
33
+ trace-events | 3 ---
34
+ vl.c | 26 --------------------------
35
+ 2 files changed, 29 deletions(-)
36
+
37
+ diff --git a/trace-events b/trace-events
38
+ index af5147a..6cd46e9 100644
39
+ --- a/trace-events
40
+ +++ b/trace-events
41
+ @@ -474,9 +474,6 @@ scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
42
+ vm_state_notify(int running, int reason) "running %d reason %d"
43
+ load_file(const char *name, const char *path) "name %s location %s"
44
+ runstate_set(int new_state) "new state %d"
45
+ -g_malloc(size_t size, void *ptr) "size %zu ptr %p"
46
+ -g_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
47
+ -g_free(void *ptr) "ptr %p"
48
+ qemu_system_shutdown_request(void) ""
49
+ qemu_system_powerdown_request(void) ""
50
+
51
+ diff --git a/vl.c b/vl.c
52
+ index 35b927e..9756361 100644
53
+ --- a/vl.c
54
+ +++ b/vl.c
55
+ @@ -2738,26 +2738,6 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
56
+ return popt;
57
+ }
58
+
59
+ -static gpointer malloc_and_trace(gsize n_bytes)
60
+ -{
61
+ - void *ptr = malloc(n_bytes);
62
+ - trace_g_malloc(n_bytes, ptr);
63
+ - return ptr;
64
+ -}
65
+ -
66
+ -static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
67
+ -{
68
+ - void *ptr = realloc(mem, n_bytes);
69
+ - trace_g_realloc(mem, n_bytes, ptr);
70
+ - return ptr;
71
+ -}
72
+ -
73
+ -static void free_and_trace(gpointer mem)
74
+ -{
75
+ - trace_g_free(mem);
76
+ - free(mem);
77
+ -}
78
+ -
79
+ static int object_set_property(const char *name, const char *value, void *opaque)
80
+ {
81
+ Object *obj = OBJECT(opaque);
82
+ @@ -2832,11 +2812,6 @@ int main(int argc, char **argv, char **envp)
83
+ bool userconfig = true;
84
+ const char *log_mask = NULL;
85
+ const char *log_file = NULL;
86
+ - GMemVTable mem_trace = {
87
+ - .malloc = malloc_and_trace,
88
+ - .realloc = realloc_and_trace,
89
+ - .free = free_and_trace,
90
+ - };
91
+ const char *trace_events = NULL;
92
+ const char *trace_file = NULL;
93
+ FILE *vmstate_dump_file = NULL;
94
+ @@ -2845,7 +2820,6 @@ int main(int argc, char **argv, char **envp)
95
+ error_set_progname(argv[0]);
96
+ qemu_init_exec_dir(argv[0]);
97
+
98
+ - g_mem_set_vtable(&mem_trace);
99
+ if (!g_thread_supported()) {
100
+ #if !GLIB_CHECK_VERSION(2, 31, 0)
101
+ g_thread_init(NULL);
102
+ --
103
+ 1.8.3.1
104
+
SOURCES/kvm-util-Fix-MIN_NON_ZERO.patch ADDED
@@ -0,0 +1,46 @@
1
+ From 756b23c15387acefe4139831c2f3c8a5f3d41bb2 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 18 Jul 2016 01:32:10 +0200
4
+ Subject: [PATCH 7/7] util: Fix MIN_NON_ZERO
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1468805530-19033-1-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 71200
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 7/6] util: Fix MIN_NON_ZERO
10
+ Bugzilla: 1318199
11
+ RH-Acked-by: John Snow <jsnow@redhat.com>
12
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
15
+
16
+ MIN_NON_ZERO(1, 0) is evaluated to 0. Rewrite the macro to fix it.
17
+
18
+ Reported-by: Miroslav Rezanina <mrezanin@redhat.com>
19
+ Signed-off-by: Fam Zheng <famz@redhat.com>
20
+ Message-Id: <1468306113-847-1-git-send-email-famz@redhat.com>
21
+ Reviewed-by: Eric Blake <eblake@redhat.com>
22
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
23
+ (cherry picked from commit d27ba624aa1dfe5c07cc01200d95967ffce905d9)
24
+ Signed-off-by: Fam Zheng <famz@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ include/qemu/osdep.h | 3 ++-
28
+ 1 file changed, 2 insertions(+), 1 deletion(-)
29
+
30
+ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
31
+ index c47a600..5ca05bc 100644
32
+ --- a/include/qemu/osdep.h
33
+ +++ b/include/qemu/osdep.h
34
+ @@ -71,7 +71,8 @@ typedef signed int int_fast16_t;
35
+ /* Minimum function that returns zero only iff both values are zero.
36
+ * Intended for use with unsigned values only. */
37
+ #ifndef MIN_NON_ZERO
38
+ -#define MIN_NON_ZERO(a, b) (((a) != 0 && (a) < (b)) ? (a) : (b))
39
+ +#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \
40
+ + ((b) == 0 ? (a) : (MIN(a, b))))
41
+ #endif
42
+
43
+ #ifndef ROUND_UP
44
+ --
45
+ 1.8.3.1
46
+
SOURCES/kvm-util-introduce-MIN_NON_ZERO.patch ADDED
@@ -0,0 +1,52 @@
1
+ From 6e14ac55a7b40804cf69de560f38561214129b07 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 11 Jul 2016 05:33:34 +0200
4
+ Subject: [PATCH 1/7] util: introduce MIN_NON_ZERO
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1468215219-30793-2-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 71105
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/6] util: introduce MIN_NON_ZERO
10
+ Bugzilla: 1318199
11
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12
+ RH-Acked-by: John Snow <jsnow@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Peter Lieven <pl@kamp.de>
16
+
17
+ at least in block layer we have the case of limits being defined for a
18
+ BlockDriverState. However, in this context often zero (0) has the special
19
+ meanining of undefined which means no limit. If two of those limits are
20
+ combined and the minimum is needed the minimum function should only return
21
+ zero if both parameters are zero.
22
+
23
+ Signed-off-by: Peter Lieven <pl@kamp.de>
24
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
25
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
26
+ (cherry picked from commit ac3a8726644d4783eacf54212d23db01d1d30044)
27
+ Signed-off-by: Fam Zheng <famz@redhat.com>
28
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
29
+ ---
30
+ include/qemu/osdep.h | 6 ++++++
31
+ 1 file changed, 6 insertions(+)
32
+
33
+ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
34
+ index 8984da0..c47a600 100644
35
+ --- a/include/qemu/osdep.h
36
+ +++ b/include/qemu/osdep.h
37
+ @@ -68,6 +68,12 @@ typedef signed int int_fast16_t;
38
+ #define MAX(a, b) (((a) > (b)) ? (a) : (b))
39
+ #endif
40
+
41
+ +/* Minimum function that returns zero only iff both values are zero.
42
+ + * Intended for use with unsigned values only. */
43
+ +#ifndef MIN_NON_ZERO
44
+ +#define MIN_NON_ZERO(a, b) (((a) != 0 && (a) < (b)) ? (a) : (b))
45
+ +#endif
46
+ +
47
+ #ifndef ROUND_UP
48
+ #define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
49
+ #endif
50
+ --
51
+ 1.8.3.1
52
+
SOURCES/kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch CHANGED
@@ -1,13 +1,13 @@
1
- From 9397be4c801c71c84bc4ba6036efea32f5426c2e Mon Sep 17 00:00:00 2001
1
+ From c5ee3f3aab59ff26b0fed770077a16714da9696e Mon Sep 17 00:00:00 2001
2
2
From: Gerd Hoffmann <kraxel@redhat.com>
3
- Date: Fri, 29 Apr 2016 07:02:46 +0200
4
- Subject: [PATCH 1/6] vga: Remove some "should be done in BIOS" comments
3
+ Date: Thu, 28 Apr 2016 16:07:27 +0200
4
+ Subject: [PATCH 22/27] vga: Remove some "should be done in BIOS" comments
5
5
6
6
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
- Message-id: <1461913371-3145-2-git-send-email-kraxel@redhat.com>
8
- Patchwork-id: 70301
9
- O-Subject: [virt-devel] [RHEL-7.2.z qemu-kvm PATCH 1/6] vga: Remove some "should be done in BIOS" comments
10
- Bugzilla: 1331412
7
+ Message-id: <1461859652-20918-2-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 70292
9
+ O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 1/6] vga: Remove some "should be done in BIOS" comments
10
+ Bugzilla: 1331413
11
11
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
12
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
@@ -20,6 +20,7 @@ using the DISPI interface to initialize the card.
20
20
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
21
21
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
22
22
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
23
+ (cherry picked from commit ace89b8ff21cc3fb20986a334e54e6e6a1ccf729)
23
24
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
24
25
---
25
26
hw/display/vga.c | 6 ++----
SOURCES/kvm-vga-add-sr_vbe-register-set.patch CHANGED
@@ -1,13 +1,13 @@
1
- From eaf59089f691d89a0811fa355e9579fd44011dbe Mon Sep 17 00:00:00 2001
1
+ From 40d4a0ec487abcde65d4175dde0c9dda45b570f9 Mon Sep 17 00:00:00 2001
2
2
From: Gerd Hoffmann <kraxel@redhat.com>
3
3
Date: Thu, 16 Jun 2016 15:30:11 +0200
4
- Subject: [PATCH] vga: add sr_vbe register set
4
+ Subject: [PATCH 2/2] vga: add sr_vbe register set
5
5
6
6
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
7
Message-id: <1466091011-8095-2-git-send-email-kraxel@redhat.com>
8
8
Patchwork-id: 70639
9
9
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] vga: add sr_vbe register set
10
- Bugzilla: 1347527
10
+ Bugzilla: 1346982
11
11
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
12
12
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13
13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
SOURCES/kvm-vga-add-vbe_enabled-helper.patch CHANGED
@@ -1,13 +1,13 @@
1
- From 0f24daf4c35cace529ae8441aa8b101ba53660ea Mon Sep 17 00:00:00 2001
1
+ From 6e615e8fbbd979134868bcd63150365d48d12137 Mon Sep 17 00:00:00 2001
2
2
From: Gerd Hoffmann <kraxel@redhat.com>
3
- Date: Fri, 29 Apr 2016 07:02:48 +0200
4
- Subject: [PATCH 3/6] vga: add vbe_enabled() helper
3
+ Date: Thu, 28 Apr 2016 16:07:29 +0200
4
+ Subject: [PATCH 24/27] vga: add vbe_enabled() helper
5
5
6
6
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
- Message-id: <1461913371-3145-4-git-send-email-kraxel@redhat.com>
8
- Patchwork-id: 70303
9
- O-Subject: [virt-devel] [RHEL-7.2.z qemu-kvm PATCH 3/6] vga: add vbe_enabled() helper
10
- Bugzilla: 1331412
7
+ Message-id: <1461859652-20918-4-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 70294
9
+ O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 3/6] vga: add vbe_enabled() helper
10
+ Bugzilla: 1331413
11
11
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
12
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
SOURCES/kvm-vga-factor-out-vga-register-setup.patch CHANGED
@@ -1,13 +1,13 @@
1
- From c3eb11a92f0fa90fe2976c9c5ea59fe8ab862e77 Mon Sep 17 00:00:00 2001
1
+ From 445ec835479fd06142078a59f1a88f2b30708930 Mon Sep 17 00:00:00 2001
2
2
From: Gerd Hoffmann <kraxel@redhat.com>
3
- Date: Fri, 29 Apr 2016 07:02:49 +0200
4
- Subject: [PATCH 4/6] vga: factor out vga register setup
3
+ Date: Thu, 28 Apr 2016 16:07:30 +0200
4
+ Subject: [PATCH 25/27] vga: factor out vga register setup
5
5
6
6
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
- Message-id: <1461913371-3145-5-git-send-email-kraxel@redhat.com>
8
- Patchwork-id: 70304
9
- O-Subject: [virt-devel] [RHEL-7.2.z qemu-kvm PATCH 4/6] vga: factor out vga register setup
10
- Bugzilla: 1331412
7
+ Message-id: <1461859652-20918-5-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 70295
9
+ O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 4/6] vga: factor out vga register setup
10
+ Bugzilla: 1331413
11
11
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
12
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
SOURCES/kvm-vga-fix-banked-access-bounds-checking-CVE-2016-xxxx.patch SOURCES/kvm-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch
file renamed
+7 -8
SOURCES/{kvm-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch → kvm-vga-fix-banked-access-bounds-checking-CVE-2016-xxxx.patch} RENAMED
@@ -1,13 +1,13 @@
1
- From 73714beab12fec056f3b38a7c2bc35a520405953 Mon Sep 17 00:00:00 2001
1
+ From 27bca97bf22a55b1be7611e07c7592fcef5dd7cc Mon Sep 17 00:00:00 2001
2
2
From: Gerd Hoffmann <kraxel@redhat.com>
3
- Date: Fri, 29 Apr 2016 07:02:47 +0200
4
- Subject: [PATCH 2/6] vga: fix banked access bounds checking (CVE-2016-3710)
3
+ Date: Thu, 28 Apr 2016 16:07:28 +0200
4
+ Subject: [PATCH 23/27] vga: fix banked access bounds checking (CVE-2016-xxxx).
5
5
6
6
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
- Message-id: <1461913371-3145-3-git-send-email-kraxel@redhat.com>
8
- Patchwork-id: 70302
9
- O-Subject: [virt-devel] [RHEL-7.2.z qemu-kvm PATCH 2/6] vga: fix banked access bounds checking (CVE-2016-3710)
10
- Bugzilla: 1331412
7
+ Message-id: <1461859652-20918-3-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 70293
9
+ O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 2/6] vga: fix banked access bounds checking (CVE-2016-xxxx).
10
+ Bugzilla: 1331413
11
11
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
12
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
@@ -28,7 +28,6 @@ can easily change access modes after setting the bank register.
28
28
Drop the bogus check, add range checks to vga_mem_{readb,writeb}
29
29
instead.
30
30
31
- Fixes: CVE-2016-3710
32
31
Reported-by: Qinghao Tang <luodalongde@gmail.com>
33
32
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
34
33
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
SOURCES/kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch CHANGED
@@ -1,13 +1,13 @@
1
- From d4916c5677937634c50737ac3caa9b6823789f4f Mon Sep 17 00:00:00 2001
1
+ From 3c18025a495a2c105c2c33051ece0f3525d1e0c4 Mon Sep 17 00:00:00 2001
2
2
From: Gerd Hoffmann <kraxel@redhat.com>
3
- Date: Fri, 29 Apr 2016 07:02:51 +0200
4
- Subject: [PATCH 6/6] vga: make sure vga register setup for vbe stays intact.
3
+ Date: Thu, 28 Apr 2016 16:07:32 +0200
4
+ Subject: [PATCH 27/27] vga: make sure vga register setup for vbe stays intact.
5
5
6
6
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
- Message-id: <1461913371-3145-7-git-send-email-kraxel@redhat.com>
8
- Patchwork-id: 70306
9
- O-Subject: [virt-devel] [RHEL-7.2.z qemu-kvm PATCH 6/6] vga: make sure vga register setup for vbe stays intact.
10
- Bugzilla: 1331412
7
+ Message-id: <1461859652-20918-7-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 70297
9
+ O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 6/6] vga: make sure vga register setup for vbe stays intact.
10
+ Bugzilla: 1331413
11
11
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
12
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
SOURCES/kvm-vga-update-vga-register-setup-on-vbe-changes.patch CHANGED
@@ -1,13 +1,13 @@
1
- From 1dfb069237e2ddf979407841a2907cd332017924 Mon Sep 17 00:00:00 2001
1
+ From 6bf28a8a9e2e6d6505f2a906b7fc532427037c5f Mon Sep 17 00:00:00 2001
2
2
From: Gerd Hoffmann <kraxel@redhat.com>
3
- Date: Fri, 29 Apr 2016 07:02:50 +0200
4
- Subject: [PATCH 5/6] vga: update vga register setup on vbe changes
3
+ Date: Thu, 28 Apr 2016 16:07:31 +0200
4
+ Subject: [PATCH 26/27] vga: update vga register setup on vbe changes
5
5
6
6
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7
- Message-id: <1461913371-3145-6-git-send-email-kraxel@redhat.com>
8
- Patchwork-id: 70305
9
- O-Subject: [virt-devel] [RHEL-7.2.z qemu-kvm PATCH 5/6] vga: update vga register setup on vbe changes
10
- Bugzilla: 1331412
7
+ Message-id: <1461859652-20918-6-git-send-email-kraxel@redhat.com>
8
+ Patchwork-id: 70296
9
+ O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 5/6] vga: update vga register setup on vbe changes
10
+ Bugzilla: 1331413
11
11
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
12
12
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
13
13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
SOURCES/kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch CHANGED
@@ -1,7 +1,7 @@
1
- From 328d99710a005b9042c4d4c423f3f5a21f0e8ead Mon Sep 17 00:00:00 2001
1
+ From acb67d9c43f3921861eebbabb447a85644e99320 Mon Sep 17 00:00:00 2001
2
2
From: Stefan Hajnoczi <stefanha@redhat.com>
3
3
Date: Mon, 25 Jul 2016 12:55:36 +0200
4
- Subject: [PATCH] virtio: error out if guest exceeds virtqueue size
4
+ Subject: [PATCH 2/2] virtio: error out if guest exceeds virtqueue size
5
5
MIME-Version: 1.0
6
6
Content-Type: text/plain; charset=UTF-8
7
7
Content-Transfer-Encoding: 8bit
@@ -10,7 +10,7 @@ RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
10
10
Message-id: <1469451336-20117-2-git-send-email-stefanha@redhat.com>
11
11
Patchwork-id: 71428
12
12
O-Subject: [virt-devel] [RHEL-7.3 EMBARGOED qemu-kvm PATCH 1/1] virtio: error out if guest exceeds virtqueue size
13
- Bugzilla: 1359728
13
+ Bugzilla: 1359729
14
14
RH-Acked-by: Thomas Huth <thuth@redhat.com>
15
15
RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
16
16
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
SOURCES/kvm-virtio-recalculate-vq-inuse-after-migration.patch ADDED
@@ -0,0 +1,73 @@
1
+ From 4d0430b1f847d672a39c76e6567bb5e88bc33c78 Mon Sep 17 00:00:00 2001
2
+ From: Stefan Hajnoczi <stefanha@redhat.com>
3
+ Date: Fri, 16 Sep 2016 08:38:18 +0200
4
+ Subject: [PATCH] virtio: recalculate vq->inuse after migration
5
+
6
+ RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
7
+ Message-id: <1474015098-11019-2-git-send-email-stefanha@redhat.com>
8
+ Patchwork-id: 72372
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] virtio: recalculate vq->inuse after migration
10
+ Bugzilla: 1376542
11
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
12
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
13
+ RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
14
+
15
+ The vq->inuse field is not migrated. Many devices don't hold
16
+ VirtQueueElements across migration so it doesn't matter that vq->inuse
17
+ starts at 0 on the destination QEMU.
18
+
19
+ At least virtio-serial, virtio-blk, and virtio-balloon migrate while
20
+ holding VirtQueueElements. For these devices we need to recalculate
21
+ vq->inuse upon load so the value is correct.
22
+
23
+ Cc: qemu-stable@nongnu.org
24
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
25
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
26
+ Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
27
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
28
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
29
+ (cherry picked from commit bccdef6b1a204db0f41ffb6e24ce373e4d7890d4)
30
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
31
+
32
+ Conflicts:
33
+
34
+ hw/virtio/virtio.c
35
+
36
+ Downstream does not have the vq->used_idx field which was added
37
+ upstream as a performance optimization reducing guest memory accesses.
38
+ Replace vq->used_idx with vring_used_idx(&vdev->vq[i]).
39
+
40
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
41
+ ---
42
+ hw/virtio/virtio.c | 15 +++++++++++++++
43
+ 1 file changed, 15 insertions(+)
44
+
45
+ diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
46
+ index e67337b..0df4ed3 100644
47
+ --- a/hw/virtio/virtio.c
48
+ +++ b/hw/virtio/virtio.c
49
+ @@ -932,6 +932,21 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
50
+ vdev->vq[i].last_avail_idx, nheads);
51
+ return -1;
52
+ }
53
+ +
54
+ + /*
55
+ + * Some devices migrate VirtQueueElements that have been popped
56
+ + * from the avail ring but not yet returned to the used ring.
57
+ + */
58
+ + vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
59
+ + vring_used_idx(&vdev->vq[i]);
60
+ + if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
61
+ + error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
62
+ + "used_idx 0x%x",
63
+ + i, vdev->vq[i].vring.num,
64
+ + vdev->vq[i].last_avail_idx,
65
+ + vring_used_idx(&vdev->vq[i]));
66
+ + return -1;
67
+ + }
68
+ } else if (vdev->vq[i].last_avail_idx) {
69
+ error_report("VQ %d address 0x0 "
70
+ "inconsistent with Host index 0x%x",
71
+ --
72
+ 1.8.3.1
73
+
SOURCES/kvm-virtio-scsi-Prevent-assertion-on-missed-events.patch ADDED
@@ -0,0 +1,46 @@
1
+ From 3fdd5ce3ece26d5fd0d7702e08167bf5e513f620 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 18 Apr 2016 02:50:12 +0200
4
+ Subject: [PATCH 01/10] virtio-scsi: Prevent assertion on missed events
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1460947812-5704-1-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 70202
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH] virtio-scsi: Prevent assertion on missed events
10
+ Bugzilla: 1312289
11
+ RH-Acked-by: Thomas Huth <thuth@redhat.com>
12
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13
+ RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
14
+
15
+ From: Eric Farman <farman@linux.vnet.ibm.com>
16
+
17
+ In some cases, an unplug can cause events to be dropped, which
18
+ leads to an assertion failure when preparing to notify the guest
19
+ kernel.
20
+
21
+ Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
22
+ Cc: qemu-stable@nongnu.org
23
+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
24
+ (cherry picked from commit 49fb65c7f985baa56d2964e0a85c1f098e3e2a9d)
25
+ Signed-off-by: Fam Zheng <famz@redhat.com>
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+ ---
28
+ hw/scsi/virtio-scsi.c | 2 +-
29
+ 1 file changed, 1 insertion(+), 1 deletion(-)
30
+
31
+ diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
32
+ index 8232fc9..808eb54 100644
33
+ --- a/hw/scsi/virtio-scsi.c
34
+ +++ b/hw/scsi/virtio-scsi.c
35
+ @@ -530,7 +530,7 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
36
+ evt->event = event;
37
+ evt->reason = reason;
38
+ if (!dev) {
39
+ - assert(event == VIRTIO_SCSI_T_NO_EVENT);
40
+ + assert(event == VIRTIO_SCSI_T_EVENTS_MISSED);
41
+ } else {
42
+ evt->lun[0] = 1;
43
+ evt->lun[1] = dev->id;
44
+ --
45
+ 1.8.3.1
46
+
SOURCES/kvm-virtio-validate-the-existence-of-handle_output-befor.patch ADDED
@@ -0,0 +1,59 @@
1
+ From 612017cc4834cd5eabc12afc7dd6cebf890b42e5 Mon Sep 17 00:00:00 2001
2
+ From: Xiao Wang <jasowang@redhat.com>
3
+ Date: Fri, 19 Aug 2016 09:24:25 +0200
4
+ Subject: [PATCH] virtio: validate the existence of handle_output before
5
+ calling it
6
+
7
+ RH-Author: Xiao Wang <jasowang@redhat.com>
8
+ Message-id: <1471598665-23846-1-git-send-email-jasowang@redhat.com>
9
+ Patchwork-id: 72021
10
+ O-Subject: [RHEL7.3 qemu-kvm PATCH] virtio: validate the existence of handle_output before calling it
11
+ Bugzilla: 1367040
12
+ RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13
+ RH-Acked-by: Fam Zheng <famz@redhat.com>
14
+ RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
15
+
16
+ Bugzilla: 1367040
17
+ Brew Build: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=11620539
18
+ Test status: Tested by myself.
19
+
20
+ We don't validate the existence of handle_output which may let a buggy
21
+ guest to trigger a SIGSEV easily. E.g:
22
+
23
+ 1) write 10 to queue_sel to a virtio net device with only 1 queue
24
+ 2) setup an arbitrary pfn
25
+ 3) then notify queue 10
26
+
27
+ Fixing this by validating the existence of handle_output before.
28
+
29
+ Cc: qemu-stable@nongnu.org
30
+ Cc: Michael S. Tsirkin <mst@redhat.com>
31
+ Signed-off-by: Jason Wang <jasowang@redhat.com>
32
+ Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
33
+ Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
34
+ Reviewed-by: Don Koch <dkoch@verizon.com>
35
+ Reviewed-by: Fam Zheng <famz@redhat.com>
36
+ (cherry picked from commit 9e0f5b8108e248b78444c9a2ec41a8309825736c)
37
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
38
+ ---
39
+ hw/virtio/virtio.c | 3 ++-
40
+ 1 file changed, 2 insertions(+), 1 deletion(-)
41
+
42
+ diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
43
+ index a861870..e67337b 100644
44
+ --- a/hw/virtio/virtio.c
45
+ +++ b/hw/virtio/virtio.c
46
+ @@ -692,8 +692,9 @@ int virtio_queue_get_id(VirtQueue *vq)
47
+
48
+ void virtio_queue_notify_vq(VirtQueue *vq)
49
+ {
50
+ - if (vq->vring.desc) {
51
+ + if (vq->vring.desc && vq->handle_output) {
52
+ VirtIODevice *vdev = vq->vdev;
53
+ +
54
+ trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
55
+ vq->handle_output(vdev, vq);
56
+ }
57
+ --
58
+ 1.8.3.1
59
+
SOURCES/kvm-vmdk-Check-descriptor-file-length-when-reading-it.patch ADDED
@@ -0,0 +1,56 @@
1
+ From 86c71987b64382e1177f86e6bc00bfc19e20082d Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:18 +0100
4
+ Subject: [PATCH 05/18] vmdk: Check descriptor file length when reading it
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-6-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69171
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 05/18] vmdk: Check descriptor file length when reading it
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ Since a too small file cannot be a valid VMDK image, and also since the
18
+ buffer's first 4 bytes will be unconditionally examined by
19
+ vmdk_open_sparse, let's error out the small file case to be clear.
20
+
21
+ Signed-off-by: Fam Zheng <famz@redhat.com>
22
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
23
+ Reviewed-by: Markus Armbruster <armbru@redhat.com>
24
+ Reviewed-by: Don Koch <dkoch@verizon.com>
25
+ Message-id: 1417649314-13704-5-git-send-email-famz@redhat.com
26
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
27
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
+ (cherry picked from commit 03c3359dfc490eaf922f88955d6a8cc51a37ce92)
29
+ Signed-off-by: Fam Zheng <famz@redhat.com>
30
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
31
+ ---
32
+ block/vmdk.c | 8 ++++++++
33
+ 1 file changed, 8 insertions(+)
34
+
35
+ diff --git a/block/vmdk.c b/block/vmdk.c
36
+ index 3dfbd41..db3cdc0 100644
37
+ --- a/block/vmdk.c
38
+ +++ b/block/vmdk.c
39
+ @@ -559,6 +559,14 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
40
+ return NULL;
41
+ }
42
+
43
+ + if (size < 4) {
44
+ + /* Both descriptor file and sparse image must be much larger than 4
45
+ + * bytes, also callers of vmdk_read_desc want to compare the first 4
46
+ + * bytes with VMDK4_MAGIC, let's error out if less is read. */
47
+ + error_setg(errp, "File is too small, not a valid image");
48
+ + return NULL;
49
+ + }
50
+ +
51
+ size = MIN(size, (1 << 20) - 1); /* avoid unbounded allocation */
52
+ buf = g_malloc(size + 1);
53
+
54
+ --
55
+ 1.8.3.1
56
+
SOURCES/kvm-vmdk-Clean-up-descriptor-file-reading.patch ADDED
@@ -0,0 +1,60 @@
1
+ From 2aa26696846adf25a41fa082f4d42c98b2b05fe3 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:17 +0100
4
+ Subject: [PATCH 04/18] vmdk: Clean up descriptor file reading
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-5-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69170
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 04/18] vmdk: Clean up descriptor file reading
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ Zeroing a buffer that will be filled right after is not necessary, and
18
+ allocating a power of two + 1 is naughty.
19
+
20
+ Suggested-by: Markus Armbruster <armbru@redhat.com>
21
+ Signed-off-by: Fam Zheng <famz@redhat.com>
22
+ Reviewed-by: Don Koch <dkoch@verizon.com>
23
+ Reviewed-by: Markus Armbruster <armbru@redhat.com>
24
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
25
+ Message-id: 1417649314-13704-4-git-send-email-famz@redhat.com
26
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
27
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
+ (cherry picked from commit 73b7bcad439e0edaced05049897090cc10d84b5b)
29
+ Signed-off-by: Fam Zheng <famz@redhat.com>
30
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
31
+ ---
32
+ block/vmdk.c | 5 +++--
33
+ 1 file changed, 3 insertions(+), 2 deletions(-)
34
+
35
+ diff --git a/block/vmdk.c b/block/vmdk.c
36
+ index 3f34abf..3dfbd41 100644
37
+ --- a/block/vmdk.c
38
+ +++ b/block/vmdk.c
39
+ @@ -559,8 +559,8 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
40
+ return NULL;
41
+ }
42
+
43
+ - size = MIN(size, 1 << 20); /* avoid unbounded allocation */
44
+ - buf = g_malloc0(size + 1);
45
+ + size = MIN(size, (1 << 20) - 1); /* avoid unbounded allocation */
46
+ + buf = g_malloc(size + 1);
47
+
48
+ ret = bdrv_pread(file, desc_offset, buf, size);
49
+ if (ret < 0) {
50
+ @@ -568,6 +568,7 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
51
+ g_free(buf);
52
+ return NULL;
53
+ }
54
+ + buf[ret] = 0;
55
+
56
+ return buf;
57
+ }
58
+ --
59
+ 1.8.3.1
60
+
SOURCES/kvm-vmdk-Create-streamOptimized-as-version-3.patch ADDED
@@ -0,0 +1,51 @@
1
+ From 7777177c3c7291ff5c4b24040b075a1bd1c1db77 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:29 +0100
4
+ Subject: [PATCH 16/18] vmdk: Create streamOptimized as version 3
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-17-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69182
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 16/18] vmdk: Create streamOptimized as version 3
10
+ Bugzilla: 1299116
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299116
16
+
17
+ VMware products accept only version 3 for streamOptimized, let's bump
18
+ the version.
19
+
20
+ Reported-by: Radoslav Gerganov <rgerganov@vmware.com>
21
+ Signed-off-by: Fam Zheng <famz@redhat.com>
22
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
+ (cherry picked from commit d62d9dc4b814950dcc8bd261a3e2e9300d9065e6)
24
+ Signed-off-by: Fam Zheng <famz@redhat.com>
25
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26
+ ---
27
+ block/vmdk.c | 8 +++++++-
28
+ 1 file changed, 7 insertions(+), 1 deletion(-)
29
+
30
+ diff --git a/block/vmdk.c b/block/vmdk.c
31
+ index 7009660..7b3e397 100644
32
+ --- a/block/vmdk.c
33
+ +++ b/block/vmdk.c
34
+ @@ -1658,7 +1658,13 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
35
+ }
36
+ magic = cpu_to_be32(VMDK4_MAGIC);
37
+ memset(&header, 0, sizeof(header));
38
+ - header.version = zeroed_grain ? 2 : 1;
39
+ + if (compress) {
40
+ + header.version = 3;
41
+ + } else if (zeroed_grain) {
42
+ + header.version = 2;
43
+ + } else {
44
+ + header.version = 1;
45
+ + }
46
+ header.flags = VMDK4_FLAG_RGD | VMDK4_FLAG_NL_DETECT
47
+ | (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0)
48
+ | (zeroed_grain ? VMDK4_FLAG_ZERO_GRAIN : 0);
49
+ --
50
+ 1.8.3.1
51
+
SOURCES/kvm-vmdk-Fix-calculation-of-block-status-s-offset.patch ADDED
@@ -0,0 +1,60 @@
1
+ From 0cdb7038a7027cbb63c820e60bb34abd191ac85f Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:31 +0100
4
+ Subject: [PATCH 18/18] vmdk: Fix calculation of block status's offset
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-19-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69184
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 18/18] vmdk: Fix calculation of block status's offset
10
+ Bugzilla: 1299116
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ "offset" is the offset of cluster and sector_num doesn't necessarily
16
+ refer to the start of it, it should add index_in_cluster.
17
+
18
+ Signed-off-by: Fam Zheng <famz@redhat.com>
19
+ Message-id: 1453780743-16806-12-git-send-email-famz@redhat.com
20
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
21
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
22
+ (cherry picked from commit d0a18f10251f515c86dcaec5bdf979a4e07fafc5)
23
+ Signed-off-by: Fam Zheng <famz@redhat.com>
24
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
25
+ ---
26
+ block/vmdk.c | 6 ++++--
27
+ 1 file changed, 4 insertions(+), 2 deletions(-)
28
+
29
+ diff --git a/block/vmdk.c b/block/vmdk.c
30
+ index b0c312b..b4f0d44 100644
31
+ --- a/block/vmdk.c
32
+ +++ b/block/vmdk.c
33
+ @@ -1275,6 +1275,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
34
+ 0, 0);
35
+ qemu_co_mutex_unlock(&s->lock);
36
+
37
+ + index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
38
+ switch (ret) {
39
+ case VMDK_ERROR:
40
+ ret = -EIO;
41
+ @@ -1288,13 +1289,14 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
42
+ case VMDK_OK:
43
+ ret = BDRV_BLOCK_DATA;
44
+ if (extent->file == bs->file && !extent->compressed) {
45
+ - ret |= BDRV_BLOCK_OFFSET_VALID | offset;
46
+ + ret |= BDRV_BLOCK_OFFSET_VALID;
47
+ + ret |= (offset + (index_in_cluster << BDRV_SECTOR_BITS))
48
+ + & BDRV_BLOCK_OFFSET_MASK;
49
+ }
50
+
51
+ break;
52
+ }
53
+
54
+ - index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
55
+ n = extent->cluster_sectors - index_in_cluster;
56
+ if (n > nb_sectors) {
57
+ n = nb_sectors;
58
+ --
59
+ 1.8.3.1
60
+
SOURCES/kvm-vmdk-Fix-comment-to-match-code-of-extent-lines.patch ADDED
@@ -0,0 +1,56 @@
1
+ From ad76b22d2d96499bbbd1172f347b4ec8a2327c7d Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:16 +0100
4
+ Subject: [PATCH 03/18] vmdk: Fix comment to match code of extent lines
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-4-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69169
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 03/18] vmdk: Fix comment to match code of extent lines
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ commit 04d542c8b (vmdk: support vmfs files) added support of VMFS extent
18
+ type but the comment above the changed code is left out. Update the
19
+ comment so they are consistent.
20
+
21
+ Signed-off-by: Fam Zheng <famz@redhat.com>
22
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
23
+ Reviewed-by: Markus Armbruster <armbru@redhat.com>
24
+ Reviewed-by: Don Koch <dkoch@verizon.com>
25
+ Message-id: 1417649314-13704-3-git-send-email-famz@redhat.com
26
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
27
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
+ (cherry picked from commit 8a3e0bc370de9274170b82f48b0393204c3fb43b)
29
+ Signed-off-by: Fam Zheng <famz@redhat.com>
30
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
31
+ ---
32
+ block/vmdk.c | 6 ++++--
33
+ 1 file changed, 4 insertions(+), 2 deletions(-)
34
+
35
+ diff --git a/block/vmdk.c b/block/vmdk.c
36
+ index a9f5bab..3f34abf 100644
37
+ --- a/block/vmdk.c
38
+ +++ b/block/vmdk.c
39
+ @@ -788,10 +788,12 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
40
+ VmdkExtent *extent;
41
+
42
+ while (*p) {
43
+ - /* parse extent line:
44
+ + /* parse extent line in one of below formats:
45
+ + *
46
+ * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
47
+ - * or
48
+ * RW [size in sectors] SPARSE "file-name.vmdk"
49
+ + * RW [size in sectors] VMFS "file-name.vmdk"
50
+ + * RW [size in sectors] VMFSSPARSE "file-name.vmdk"
51
+ */
52
+ flat_offset = -1;
53
+ ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
54
+ --
55
+ 1.8.3.1
56
+
SOURCES/kvm-vmdk-Fix-converting-to-streamOptimized.patch ADDED
@@ -0,0 +1,65 @@
1
+ From b72998772910dbd04c86a2332b1c69ac1afc7a9e Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:30 +0100
4
+ Subject: [PATCH 17/18] vmdk: Fix converting to streamOptimized
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-18-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69183
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 17/18] vmdk: Fix converting to streamOptimized
10
+ Bugzilla: 1299116
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299116
16
+
17
+ Commit d62d9dc4b8 lifted streamOptimized images's version to 3, but we
18
+ now refuse to open version 3 images read-write. We need to make
19
+ streamOptimized an exception to allow converting to it. This fixes the
20
+ accidentally broken iotests case 059 for the same reason.
21
+
22
+ Signed-off-by: Fam Zheng <famz@redhat.com>
23
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
25
+ (cherry picked from commit 3db1d98a20262228373bb973ca62b1ab64b29af4)
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+ ---
29
+ block/vmdk.c | 6 +++++-
30
+ 1 file changed, 5 insertions(+), 1 deletion(-)
31
+
32
+ diff --git a/block/vmdk.c b/block/vmdk.c
33
+ index 7b3e397..b0c312b 100644
34
+ --- a/block/vmdk.c
35
+ +++ b/block/vmdk.c
36
+ @@ -592,6 +592,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
37
+ VmdkExtent *extent;
38
+ BDRVVmdkState *s = bs->opaque;
39
+ int64_t l1_backup_offset = 0;
40
+ + bool compressed;
41
+
42
+ ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
43
+ if (ret < 0) {
44
+ @@ -666,6 +667,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
45
+ header = footer.header;
46
+ }
47
+
48
+ + compressed =
49
+ + le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
50
+ if (le32_to_cpu(header.version) > 3) {
51
+ char buf[64];
52
+ snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
53
+ @@ -673,7 +676,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
54
+ error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
55
+ bs->device_name, "vmdk", buf);
56
+ return -ENOTSUP;
57
+ - } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
58
+ + } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) &&
59
+ + !compressed) {
60
+ /* VMware KB 2064959 explains that version 3 added support for
61
+ * persistent changed block tracking (CBT), and backup software can
62
+ * read it as version=1 if it doesn't care about the changed area
63
+ --
64
+ 1.8.3.1
65
+
SOURCES/kvm-vmdk-Fix-index_in_cluster-calculation-in-vmdk_co_get.patch ADDED
@@ -0,0 +1,65 @@
1
+ From 32791762f04b3342e9b10d1f553326cd01ea451f Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:26 +0100
4
+ Subject: [PATCH 13/18] vmdk: Fix index_in_cluster calculation in
5
+ vmdk_co_get_block_status
6
+
7
+ RH-Author: Fam Zheng <famz@redhat.com>
8
+ Message-id: <1455528511-9357-14-git-send-email-famz@redhat.com>
9
+ Patchwork-id: 69179
10
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 13/18] vmdk: Fix index_in_cluster calculation in vmdk_co_get_block_status
11
+ Bugzilla: 1299250
12
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
13
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
14
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
15
+
16
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
17
+
18
+ It has the similar issue with b1649fae49a8. Since the calculation
19
+ is repeated for a few times already, introduce a function so it can be
20
+ reused.
21
+
22
+ Signed-off-by: Fam Zheng <famz@redhat.com>
23
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
24
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
+ (cherry picked from commit 61f0ed1d54601b91b8195c1a30d7046f83283b40)
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+ ---
29
+ block/vmdk.c | 13 ++++++++++++-
30
+ 1 file changed, 12 insertions(+), 1 deletion(-)
31
+
32
+ diff --git a/block/vmdk.c b/block/vmdk.c
33
+ index dd8b638..10c08f3 100644
34
+ --- a/block/vmdk.c
35
+ +++ b/block/vmdk.c
36
+ @@ -1242,6 +1242,17 @@ static VmdkExtent *find_extent(BDRVVmdkState *s,
37
+ return NULL;
38
+ }
39
+
40
+ +static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent,
41
+ + int64_t sector_num)
42
+ +{
43
+ + uint64_t index_in_cluster, extent_begin_sector, extent_relative_sector_num;
44
+ +
45
+ + extent_begin_sector = extent->end_sector - extent->sectors;
46
+ + extent_relative_sector_num = sector_num - extent_begin_sector;
47
+ + index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
48
+ + return index_in_cluster;
49
+ +}
50
+ +
51
+ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
52
+ int64_t sector_num, int nb_sectors, int *pnum)
53
+ {
54
+ @@ -1279,7 +1290,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
55
+ break;
56
+ }
57
+
58
+ - index_in_cluster = sector_num % extent->cluster_sectors;
59
+ + index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
60
+ n = extent->cluster_sectors - index_in_cluster;
61
+ if (n > nb_sectors) {
62
+ n = nb_sectors;
63
+ --
64
+ 1.8.3.1
65
+
SOURCES/kvm-vmdk-Fix-next_cluster_sector-for-compressed-write.patch ADDED
@@ -0,0 +1,70 @@
1
+ From 47886bf3b19f06d0a5255d9656d1c02800baddd0 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:25 +0100
4
+ Subject: [PATCH 12/18] vmdk: Fix next_cluster_sector for compressed write
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-13-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69178
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 12/18] vmdk: Fix next_cluster_sector for compressed write
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ This fixes the bug introduced by commit c6ac36e (vmdk: Optimize cluster
18
+ allocation).
19
+
20
+ Sometimes, write_len could be larger than cluster size, because it
21
+ contains both data and marker. We must advance next_cluster_sector in
22
+ this case, otherwise the image gets corrupted.
23
+
24
+ Cc: qemu-stable@nongnu.org
25
+ Reported-by: Antoni Villalonga <qemu-list@friki.cat>
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
28
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
29
+ (cherry picked from commit 5e82a31eb967db135fc4e688b134fb0972d62de3)
30
+ Signed-off-by: Fam Zheng <famz@redhat.com>
31
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
32
+ ---
33
+ block/vmdk.c | 14 ++++++++++----
34
+ 1 file changed, 10 insertions(+), 4 deletions(-)
35
+
36
+ diff --git a/block/vmdk.c b/block/vmdk.c
37
+ index 3810d75..dd8b638 100644
38
+ --- a/block/vmdk.c
39
+ +++ b/block/vmdk.c
40
+ @@ -1297,6 +1297,8 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
41
+ uLongf buf_len;
42
+ const uint8_t *write_buf = buf;
43
+ int write_len = nb_sectors * 512;
44
+ + int64_t write_offset;
45
+ + int64_t write_end_sector;
46
+
47
+ if (extent->compressed) {
48
+ if (!extent->has_marker) {
49
+ @@ -1315,10 +1317,14 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
50
+ write_buf = (uint8_t *)data;
51
+ write_len = buf_len + sizeof(VmdkGrainMarker);
52
+ }
53
+ - ret = bdrv_pwrite(extent->file,
54
+ - cluster_offset + offset_in_cluster,
55
+ - write_buf,
56
+ - write_len);
57
+ + write_offset = cluster_offset + offset_in_cluster,
58
+ + ret = bdrv_pwrite(extent->file, write_offset, write_buf, write_len);
59
+ +
60
+ + write_end_sector = DIV_ROUND_UP(write_offset + write_len, BDRV_SECTOR_SIZE);
61
+ +
62
+ + extent->next_cluster_sector = MAX(extent->next_cluster_sector,
63
+ + write_end_sector);
64
+ +
65
+ if (ret != write_len) {
66
+ ret = ret < 0 ? ret : -EIO;
67
+ goto out;
68
+ --
69
+ 1.8.3.1
70
+
SOURCES/kvm-vmdk-Fix-next_cluster_sector-for-compressed-write2.patch ADDED
@@ -0,0 +1,55 @@
1
+ From bc048d2d5f362757fa0bf51add81d92ec19ad161 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:28 +0100
4
+ Subject: [PATCH 15/18] vmdk: Fix next_cluster_sector for compressed write
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-16-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69181
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 15/18] vmdk: Fix next_cluster_sector for compressed write
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ From: Radoslav Gerganov <rgerganov@vmware.com>
16
+
17
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
18
+
19
+ When the VMDK is streamOptimized (or compressed), the
20
+ next_cluster_sector must not be incremented by a fixed number of
21
+ sectors. Instead of this, it must be rounded up to the next consecutive
22
+ sector. Fixing this results in much smaller compressed images.
23
+
24
+ Signed-off-by: Radoslav Gerganov <rgerganov@vmware.com>
25
+ Reviewed-by: Fam Zheng <famz@redhat.com>
26
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
+ (cherry picked from commit 3efffc3292d94271a15b1606b4a56adf6c6f04ed)
28
+ Signed-off-by: Fam Zheng <famz@redhat.com>
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ block/vmdk.c | 8 ++++++--
32
+ 1 file changed, 6 insertions(+), 2 deletions(-)
33
+
34
+ diff --git a/block/vmdk.c b/block/vmdk.c
35
+ index cb5255c..7009660 100644
36
+ --- a/block/vmdk.c
37
+ +++ b/block/vmdk.c
38
+ @@ -1333,8 +1333,12 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
39
+
40
+ write_end_sector = DIV_ROUND_UP(write_offset + write_len, BDRV_SECTOR_SIZE);
41
+
42
+ - extent->next_cluster_sector = MAX(extent->next_cluster_sector,
43
+ - write_end_sector);
44
+ + if (extent->compressed) {
45
+ + extent->next_cluster_sector = write_end_sector;
46
+ + } else {
47
+ + extent->next_cluster_sector = MAX(extent->next_cluster_sector,
48
+ + write_end_sector);
49
+ + }
50
+
51
+ if (ret != write_len) {
52
+ ret = ret < 0 ? ret : -EIO;
53
+ --
54
+ 1.8.3.1
55
+
SOURCES/kvm-vmdk-Leave-bdi-intact-if-ENOTSUP-in-vmdk_get_info.patch ADDED
@@ -0,0 +1,74 @@
1
+ From 824614c344ceeb60dd27b38cfdb190471b6a2ef9 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:14 +0100
4
+ Subject: [PATCH 01/18] vmdk: Leave bdi intact if -ENOTSUP in vmdk_get_info
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-2-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69167
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 01/18] vmdk: Leave bdi intact if -ENOTSUP in vmdk_get_info
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ When extent types don't match, we return -ENOTSUP. In this case, be
18
+ polite to the caller and don't modify bdi.
19
+
20
+ Signed-off-by: Fam Zheng <famz@redhat.com>
21
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
22
+ Message-id: 1415938161-16217-1-git-send-email-famz@redhat.com
23
+ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
+ (cherry picked from commit 5f58330790b72c4705b373ee0646fb3adf800b4e)
25
+ Signed-off-by: Fam Zheng <famz@redhat.com>
26
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
27
+ ---
28
+ block/vmdk.c | 20 +++++++++++++-------
29
+ 1 file changed, 13 insertions(+), 7 deletions(-)
30
+
31
+ diff --git a/block/vmdk.c b/block/vmdk.c
32
+ index 6b015ab..fa53d2f 100644
33
+ --- a/block/vmdk.c
34
+ +++ b/block/vmdk.c
35
+ @@ -2137,23 +2137,29 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
36
+ return spec_info;
37
+ }
38
+
39
+ +static bool vmdk_extents_type_eq(const VmdkExtent *a, const VmdkExtent *b)
40
+ +{
41
+ + return a->flat == b->flat &&
42
+ + a->compressed == b->compressed &&
43
+ + (a->flat || a->cluster_sectors == b->cluster_sectors);
44
+ +}
45
+ +
46
+ static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
47
+ {
48
+ int i;
49
+ BDRVVmdkState *s = bs->opaque;
50
+ assert(s->num_extents);
51
+ - bdi->needs_compressed_writes = s->extents[0].compressed;
52
+ - if (!s->extents[0].flat) {
53
+ - bdi->cluster_size = s->extents[0].cluster_sectors << BDRV_SECTOR_BITS;
54
+ - }
55
+ +
56
+ /* See if we have multiple extents but they have different cases */
57
+ for (i = 1; i < s->num_extents; i++) {
58
+ - if (bdi->needs_compressed_writes != s->extents[i].compressed ||
59
+ - (bdi->cluster_size && bdi->cluster_size !=
60
+ - s->extents[i].cluster_sectors << BDRV_SECTOR_BITS)) {
61
+ + if (!vmdk_extents_type_eq(&s->extents[0], &s->extents[i])) {
62
+ return -ENOTSUP;
63
+ }
64
+ }
65
+ + bdi->needs_compressed_writes = s->extents[0].compressed;
66
+ + if (!s->extents[0].flat) {
67
+ + bdi->cluster_size = s->extents[0].cluster_sectors << BDRV_SECTOR_BITS;
68
+ + }
69
+ return 0;
70
+ }
71
+
72
+ --
73
+ 1.8.3.1
74
+
SOURCES/kvm-vmdk-Remove-unnecessary-initialization.patch ADDED
@@ -0,0 +1,49 @@
1
+ From aea042fc3e0a8454edb4e9884635af63128b15d3 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:19 +0100
4
+ Subject: [PATCH 06/18] vmdk: Remove unnecessary initialization
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-7-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69172
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 06/18] vmdk: Remove unnecessary initialization
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ It will be assigned to the return value of vmdk_read_desc.
18
+
19
+ Suggested-by: Markus Armbruster <armbru@redhat.com>
20
+ Signed-off-by: Fam Zheng <famz@redhat.com>
21
+ Reviewed-by: Markus Armbruster <armbru@redhat.com>
22
+ Reviewed-by: Don Koch <dkoch@verizon.com>
23
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
24
+ Message-id: 1417649314-13704-6-git-send-email-famz@redhat.com
25
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
26
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
+ (cherry picked from commit 9aeecbbc62ce52a94b2621a0d53567b5d4ed915d)
28
+ Signed-off-by: Fam Zheng <famz@redhat.com>
29
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
30
+ ---
31
+ block/vmdk.c | 2 +-
32
+ 1 file changed, 1 insertion(+), 1 deletion(-)
33
+
34
+ diff --git a/block/vmdk.c b/block/vmdk.c
35
+ index db3cdc0..69d8a6e 100644
36
+ --- a/block/vmdk.c
37
+ +++ b/block/vmdk.c
38
+ @@ -916,7 +916,7 @@ exit:
39
+ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
40
+ Error **errp)
41
+ {
42
+ - char *buf = NULL;
43
+ + char *buf;
44
+ int ret;
45
+ BDRVVmdkState *s = bs->opaque;
46
+ uint32_t magic;
47
+ --
48
+ 1.8.3.1
49
+
SOURCES/kvm-vmdk-Set-errp-on-failures-in-vmdk_open_vmdk4.patch ADDED
@@ -0,0 +1,62 @@
1
+ From 005308f5b469f749980310be141315e8bd46556f Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:20 +0100
4
+ Subject: [PATCH 07/18] vmdk: Set errp on failures in vmdk_open_vmdk4
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-8-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69173
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 07/18] vmdk: Set errp on failures in vmdk_open_vmdk4
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ Reported-by: Markus Armbruster <armbru@redhat.com>
18
+ Signed-off-by: Fam Zheng <famz@redhat.com>
19
+ Reviewed-by: Markus Armbruster <armbru@redhat.com>
20
+ Reviewed-by: Don Koch <dkoch@verizon.com>
21
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
22
+ Message-id: 1417649314-13704-7-git-send-email-famz@redhat.com
23
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
24
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
+ (cherry picked from commit d899d2e248b900c53dd9081bde9f110e05747433)
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+ ---
29
+ block/vmdk.c | 3 +++
30
+ 1 file changed, 3 insertions(+)
31
+
32
+ diff --git a/block/vmdk.c b/block/vmdk.c
33
+ index 69d8a6e..1247ea4 100644
34
+ --- a/block/vmdk.c
35
+ +++ b/block/vmdk.c
36
+ @@ -647,6 +647,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
37
+ bs->file->total_sectors * 512 - 1536,
38
+ &footer, sizeof(footer));
39
+ if (ret < 0) {
40
+ + error_setg_errno(errp, -ret, "Failed to read footer");
41
+ return ret;
42
+ }
43
+
44
+ @@ -658,6 +659,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
45
+ le32_to_cpu(footer.eos_marker.size) != 0 ||
46
+ le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
47
+ {
48
+ + error_setg(errp, "Invalid footer");
49
+ return -EINVAL;
50
+ }
51
+
52
+ @@ -688,6 +690,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
53
+ l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
54
+ * le64_to_cpu(header.granularity);
55
+ if (l1_entry_sectors == 0) {
56
+ + error_setg(errp, "L1 entry size is invalid");
57
+ return -EINVAL;
58
+ }
59
+ l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
60
+ --
61
+ 1.8.3.1
62
+
SOURCES/kvm-vmdk-Use-g_random_int-to-generate-CID.patch ADDED
@@ -0,0 +1,73 @@
1
+ From bf9dd867ef8d4164685cac6451e88b6c32b190b1 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:15 +0100
4
+ Subject: [PATCH 02/18] vmdk: Use g_random_int to generate CID
5
+ MIME-Version: 1.0
6
+ Content-Type: text/plain; charset=UTF-8
7
+ Content-Transfer-Encoding: 8bit
8
+
9
+ RH-Author: Fam Zheng <famz@redhat.com>
10
+ Message-id: <1455528511-9357-3-git-send-email-famz@redhat.com>
11
+ Patchwork-id: 69168
12
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 02/18] vmdk: Use g_random_int to generate CID
13
+ Bugzilla: 1299250
14
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
15
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
16
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
17
+
18
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
19
+
20
+ This replaces two "time(NULL)" invocations with "g_random_int()".
21
+ According to VMDK spec, CID "is a random 32‐bit value updated the first
22
+ time the content of the virtual disk is modified after the virtual disk
23
+ is opened". Using "seconds since epoch" is just a "lame way" to generate
24
+ it, and not completely safe because of the low precision.
25
+
26
+ Suggested-by: Markus Armbruster <armbru@redhat.com>
27
+ Signed-off-by: Fam Zheng <famz@redhat.com>
28
+ Reviewed-by: Markus Armbruster <armbru@redhat.com>
29
+ Reviewed-by: Don Koch <dkoch@verizon.com>
30
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
31
+ Message-id: 1417649314-13704-2-git-send-email-famz@redhat.com
32
+ Signed-off-by: Max Reitz <mreitz@redhat.com>
33
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
34
+ (cherry picked from commit e5dc64b8ff09cc4c186273e4461c7479739db2ae)
35
+ Signed-off-by: Fam Zheng <famz@redhat.com>
36
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
37
+ ---
38
+ block/vmdk.c | 5 +++--
39
+ 1 file changed, 3 insertions(+), 2 deletions(-)
40
+
41
+ diff --git a/block/vmdk.c b/block/vmdk.c
42
+ index fa53d2f..a9f5bab 100644
43
+ --- a/block/vmdk.c
44
+ +++ b/block/vmdk.c
45
+ @@ -28,6 +28,7 @@
46
+ #include "qemu/module.h"
47
+ #include "migration/migration.h"
48
+ #include <zlib.h>
49
+ +#include <glib.h>
50
+
51
+ #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
52
+ #define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
53
+ @@ -1540,7 +1541,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
54
+ /* update CID on the first write every time the virtual disk is
55
+ * opened */
56
+ if (!s->cid_updated) {
57
+ - ret = vmdk_write_cid(bs, time(NULL));
58
+ + ret = vmdk_write_cid(bs, g_random_int());
59
+ if (ret < 0) {
60
+ return ret;
61
+ }
62
+ @@ -1927,7 +1928,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
63
+ }
64
+ /* generate descriptor file */
65
+ desc = g_strdup_printf(desc_template,
66
+ - (uint32_t)time(NULL),
67
+ + g_random_int(),
68
+ parent_cid,
69
+ fmt,
70
+ parent_desc_line,
71
+ --
72
+ 1.8.3.1
73
+
SOURCES/kvm-vmdk-Use-vmdk_find_index_in_cluster-everywhere.patch ADDED
@@ -0,0 +1,71 @@
1
+ From f7f34dfdb448a0344210f6bfa77b67c637ffea56 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:27 +0100
4
+ Subject: [PATCH 14/18] vmdk: Use vmdk_find_index_in_cluster everywhere
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-15-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69180
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 14/18] vmdk: Use vmdk_find_index_in_cluster everywhere
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ Signed-off-by: Fam Zheng <famz@redhat.com>
18
+ Reviewed-by: Max Reitz <mreitz@redhat.com>
19
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
+ (cherry picked from commit 90df601f06de14f062d2e8dc1bc57f0decf86fd1)
21
+ Signed-off-by: Fam Zheng <famz@redhat.com>
22
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
23
+ ---
24
+ block/vmdk.c | 10 ++--------
25
+ 1 file changed, 2 insertions(+), 8 deletions(-)
26
+
27
+ diff --git a/block/vmdk.c b/block/vmdk.c
28
+ index 10c08f3..cb5255c 100644
29
+ --- a/block/vmdk.c
30
+ +++ b/block/vmdk.c
31
+ @@ -1418,7 +1418,6 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
32
+ BDRVVmdkState *s = bs->opaque;
33
+ int ret;
34
+ uint64_t n, index_in_cluster;
35
+ - uint64_t extent_begin_sector, extent_relative_sector_num;
36
+ VmdkExtent *extent = NULL;
37
+ uint64_t cluster_offset;
38
+
39
+ @@ -1430,9 +1429,7 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
40
+ ret = get_cluster_offset(bs, extent, NULL,
41
+ sector_num << 9, false, &cluster_offset,
42
+ 0, 0);
43
+ - extent_begin_sector = extent->end_sector - extent->sectors;
44
+ - extent_relative_sector_num = sector_num - extent_begin_sector;
45
+ - index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
46
+ + index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
47
+ n = extent->cluster_sectors - index_in_cluster;
48
+ if (n > nb_sectors) {
49
+ n = nb_sectors;
50
+ @@ -1494,7 +1491,6 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
51
+ VmdkExtent *extent = NULL;
52
+ int ret;
53
+ int64_t index_in_cluster, n;
54
+ - uint64_t extent_begin_sector, extent_relative_sector_num;
55
+ uint64_t cluster_offset;
56
+ VmdkMetaData m_data;
57
+
58
+ @@ -1510,9 +1506,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
59
+ if (!extent) {
60
+ return -EIO;
61
+ }
62
+ - extent_begin_sector = extent->end_sector - extent->sectors;
63
+ - extent_relative_sector_num = sector_num - extent_begin_sector;
64
+ - index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
65
+ + index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
66
+ n = extent->cluster_sectors - index_in_cluster;
67
+ if (n > nb_sectors) {
68
+ n = nb_sectors;
69
+ --
70
+ 1.8.3.1
71
+
SOURCES/kvm-vmdk-Widen-before-shifting-32-bit-header-field.patch ADDED
@@ -0,0 +1,47 @@
1
+ From 649835536d4bb1366e01ff5600d3005042dd50d5 Mon Sep 17 00:00:00 2001
2
+ From: Fam Zheng <famz@redhat.com>
3
+ Date: Mon, 15 Feb 2016 09:28:24 +0100
4
+ Subject: [PATCH 11/18] vmdk: Widen before shifting 32 bit header field
5
+
6
+ RH-Author: Fam Zheng <famz@redhat.com>
7
+ Message-id: <1455528511-9357-12-git-send-email-famz@redhat.com>
8
+ Patchwork-id: 69177
9
+ O-Subject: [RHEL-7.3 qemu-kvm PATCH 11/18] vmdk: Widen before shifting 32 bit header field
10
+ Bugzilla: 1299250
11
+ RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12
+ RH-Acked-by: Max Reitz <mreitz@redhat.com>
13
+ RH-Acked-by: Markus Armbruster <armbru@redhat.com>
14
+
15
+ BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
16
+
17
+ Coverity spotted this.
18
+
19
+ The field is 32 bits, but if it's possible to overflow in 32 bit
20
+ left shift.
21
+
22
+ Signed-off-by: Fam Zheng <famz@redhat.com>
23
+ Reviewed-by: John Snow <jsnow@redhat.com>
24
+ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
+ (cherry picked from commit 7237aecd7e8fcc3ccf7fded77b6c127b4df5d3ac)
26
+ Signed-off-by: Fam Zheng <famz@redhat.com>
27
+ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
28
+ ---
29
+ block/vmdk.c | 2 +-
30
+ 1 file changed, 1 insertion(+), 1 deletion(-)
31
+
32
+ diff --git a/block/vmdk.c b/block/vmdk.c
33
+ index 32b3d4c..3810d75 100644
34
+ --- a/block/vmdk.c
35
+ +++ b/block/vmdk.c
36
+ @@ -525,7 +525,7 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
37
+ }
38
+ ret = vmdk_add_extent(bs, file, false,
39
+ le32_to_cpu(header.disk_sectors),
40
+ - le32_to_cpu(header.l1dir_offset) << 9,
41
+ + (int64_t)le32_to_cpu(header.l1dir_offset) << 9,
42
+ 0,
43
+ le32_to_cpu(header.l1dir_size),
44
+ 4096,
45
+ --
46
+ 1.8.3.1
47
+
file modified
+565 -112
SPECS/qemu-kvm.spec CHANGED
@@ -76,7 +76,7 @@ Obsoletes: %1 < %{obsoletes_version} \
76
76
Summary: QEMU is a FAST! processor emulator
77
77
Name: %{pkgname}%{?pkgsuffix}
78
78
Version: 1.5.3
79
- Release: 105%{?dist}.7
79
+ Release: 126%{?dist}
80
80
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
81
81
Epoch: 10
82
82
License: GPLv2+ and LGPLv2+ and BSD
@@ -97,6 +97,7 @@ Requires: libseccomp >= 1.0.0
97
97
%if 0%{!?build_only_sub:1}
98
98
Requires: glusterfs-api >= 3.6.0
99
99
%endif
100
+ Requires: libusbx >= 1.0.19
100
101
# OOM killer breaks builds with parallel make on s390(x)
101
102
%ifarch s390 s390x
102
103
%define _smp_mflags %{nil}
@@ -3161,32 +3162,232 @@ Patch1551: kvm-util-uri-Add-overflow-check-to-rfc3986_parse_port.patch
3161
3162
Patch1552: kvm-qemu-iotests-Filter-qemu-io-output-in-025.patch
3162
3163
# For bz#1270341 - qemu-kvm build failure race condition in tests/ide-test
3163
3164
Patch1553: kvm-qtest-ide-test-disable-flush-test.patch
3164
- # For bz#1279389 - ceph.conf properties override qemu's command-line properties
3165
- Patch1554: kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch
3166
- # For bz#1279389 - ceph.conf properties override qemu's command-line properties
3167
- Patch1555: kvm-rbd-fix-ceph-settings-precedence.patch
3168
- # For bz#1298828 - [abrt] qemu-img: get_block_status(): qemu-img killed by SIGABRT
3169
- Patch1556: kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch
3170
- # For bz#1298047 - CVE-2016-1714 qemu-kvm: Qemu: nvram: OOB r/w access in processing firmware configurations [rhel-7.2.z]
3171
- Patch1557: kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch
3172
- # For bz#1331412 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z]
3173
- Patch1558: kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch
3174
- # For bz#1331412 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z]
3175
- Patch1559: kvm-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch
3176
- # For bz#1331412 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z]
3177
- Patch1560: kvm-vga-add-vbe_enabled-helper.patch
3178
- # For bz#1331412 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z]
3179
- Patch1561: kvm-vga-factor-out-vga-register-setup.patch
3180
- # For bz#1331412 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z]
3181
- Patch1562: kvm-vga-update-vga-register-setup-on-vbe-changes.patch
3182
- # For bz#1331412 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z]
3183
- Patch1563: kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
3184
- # For bz#1347527 - Regression from CVE-2016-3712: windows installer fails to start
3185
- Patch1564: kvm-vga-add-sr_vbe-register-set.patch
3186
- # For bz#1359728 - EMBARGOED CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.2.z]
3187
- Patch1565: kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch
3188
- # For bz#1358996 - CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.2.z]
3189
- Patch1566: kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch
3165
+ # For bz#1268879 - Camera stops work after remote-viewer re-connection [qemu-kvm]
3166
+ Patch1554: kvm-ehci-clear-suspend-bit-on-detach.patch
3167
+ # For bz#1277248 - ceph.conf properties override qemu's command-line properties
3168
+ Patch1555: kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch
3169
+ # For bz#1277248 - ceph.conf properties override qemu's command-line properties
3170
+ Patch1556: kvm-rbd-fix-ceph-settings-precedence.patch
3171
+ # For bz#1265427 - contents of MSR_TSC_AUX are not migrated
3172
+ Patch1557: kvm-target-i386-get-put-MSR_TSC_AUX-across-reset-and-mig.patch
3173
+ # For bz#1252757 - [RHEL-7.2-qmu-kvm] Package is 100% lost when ping from host to Win2012r2 guest with 64000 size
3174
+ Patch1558: kvm-rtl8139-Fix-receive-buffer-overflow-check.patch
3175
+ # For bz#1252757 - [RHEL-7.2-qmu-kvm] Package is 100% lost when ping from host to Win2012r2 guest with 64000 size
3176
+ Patch1559: kvm-rtl8139-Do-not-consume-the-packet-during-overflow-in.patch
3177
+ # For bz#1283116 - [abrt] qemu-img: get_block_status(): qemu-img killed by SIGABRT
3178
+ Patch1560: kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch
3179
+ # For bz#1269738 - Vlan table display repeat four times in qmp when queues=4
3180
+ Patch1561: kvm-net-Make-qmp_query_rx_filter-with-name-argument-more.patch
3181
+ # For bz#1298048 - CVE-2016-1714 qemu-kvm: Qemu: nvram: OOB r/w access in processing firmware configurations [rhel-7.3]
3182
+ Patch1562: kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch
3183
+ # For bz#1296044 - qemu-kvm: insufficient loop termination conditions in start_xmit() and e1000_receive() [rhel-7.3]
3184
+ Patch1563: kvm-e1000-eliminate-infinite-loops-on-out-of-bounds-tran.patch
3185
+ # For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
3186
+ Patch1564: kvm-nbd-Always-call-close_fn-in-nbd_client_new.patch
3187
+ # For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
3188
+ Patch1565: kvm-nbd-server-Coroutine-based-negotiation.patch
3189
+ # For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
3190
+ Patch1566: kvm-nbd-client_close-on-error-in-nbd_co_client_start.patch
3191
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3192
+ Patch1567: kvm-qemu-io-Remove-unused-args_command.patch
3193
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3194
+ Patch1568: kvm-cutils-Support-P-and-E-suffixes-in-strtosz.patch
3195
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3196
+ Patch1569: kvm-qemu-io-Make-cvtnum-a-wrapper-around-strtosz_suffix.patch
3197
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3198
+ Patch1570: kvm-qemu-io-Handle-cvtnum-errors-in-alloc.patch
3199
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3200
+ Patch1571: kvm-qemu-io-Don-t-use-global-bs-in-command-implementatio.patch
3201
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3202
+ Patch1572: kvm-qemu-io-Split-off-commands-to-qemu-io-cmds.c.patch
3203
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3204
+ Patch1573: kvm-qemu-io-Factor-out-qemuio_command.patch
3205
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3206
+ Patch1574: kvm-qemu-io-Move-help-function.patch
3207
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3208
+ Patch1575: kvm-qemu-io-Move-quit-function.patch
3209
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3210
+ Patch1576: kvm-qemu-io-Move-qemu_strsep-to-cutils.c.patch
3211
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3212
+ Patch1577: kvm-qemu-io-Move-functions-for-registering-and-running-c.patch
3213
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3214
+ Patch1578: kvm-qemu-io-Move-command_loop-and-friends.patch
3215
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3216
+ Patch1579: kvm-qemu-io-Move-remaining-helpers-from-cmd.c.patch
3217
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3218
+ Patch1580: kvm-qemu-io-Interface-cleanup.patch
3219
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3220
+ Patch1581: kvm-qemu-io-Use-the-qemu-version-for-V.patch
3221
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3222
+ Patch1582: kvm-Make-qemu-io-commands-available-in-HMP.patch
3223
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3224
+ Patch1583: kvm-blkdebug-Add-BLKDBG_FLUSH_TO_OS-DISK-events.patch
3225
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3226
+ Patch1584: kvm-qemu-io-fix-cvtnum-lval-types.patch
3227
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3228
+ Patch1585: kvm-qemu-io-Check-for-trailing-chars.patch
3229
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3230
+ Patch1586: kvm-qemu-io-Correct-error-messages.patch
3231
+ # For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
3232
+ Patch1587: kvm-ide-test-fix-failure-for-test_flush.patch
3233
+ # For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
3234
+ Patch1588: kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch
3235
+ # For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
3236
+ Patch1589: kvm-vga-fix-banked-access-bounds-checking-CVE-2016-xxxx.patch
3237
+ # For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
3238
+ Patch1590: kvm-vga-add-vbe_enabled-helper.patch
3239
+ # For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
3240
+ Patch1591: kvm-vga-factor-out-vga-register-setup.patch
3241
+ # For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
3242
+ Patch1592: kvm-vga-update-vga-register-setup-on-vbe-changes.patch
3243
+ # For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
3244
+ Patch1593: kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
3245
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3246
+ Patch1594: kvm-vmdk-Leave-bdi-intact-if-ENOTSUP-in-vmdk_get_info.patch
3247
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3248
+ Patch1595: kvm-vmdk-Use-g_random_int-to-generate-CID.patch
3249
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3250
+ Patch1596: kvm-vmdk-Fix-comment-to-match-code-of-extent-lines.patch
3251
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3252
+ Patch1597: kvm-vmdk-Clean-up-descriptor-file-reading.patch
3253
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3254
+ Patch1598: kvm-vmdk-Check-descriptor-file-length-when-reading-it.patch
3255
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3256
+ Patch1599: kvm-vmdk-Remove-unnecessary-initialization.patch
3257
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3258
+ Patch1600: kvm-vmdk-Set-errp-on-failures-in-vmdk_open_vmdk4.patch
3259
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3260
+ Patch1601: kvm-block-vmdk-make-ret-variable-usage-clear.patch
3261
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3262
+ Patch1602: kvm-block-vmdk-move-string-allocations-from-stack-to-the.patch
3263
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3264
+ Patch1603: kvm-block-vmdk-fixed-sizeof-error.patch
3265
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3266
+ Patch1604: kvm-vmdk-Widen-before-shifting-32-bit-header-field.patch
3267
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3268
+ Patch1605: kvm-vmdk-Fix-next_cluster_sector-for-compressed-write.patch
3269
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3270
+ Patch1606: kvm-vmdk-Fix-index_in_cluster-calculation-in-vmdk_co_get.patch
3271
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3272
+ Patch1607: kvm-vmdk-Use-vmdk_find_index_in_cluster-everywhere.patch
3273
+ # For bz#1299250 - qemu-img created VMDK images are unbootable
3274
+ Patch1608: kvm-vmdk-Fix-next_cluster_sector-for-compressed-write2.patch
3275
+ # For bz#1299116 - qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)"
3276
+ Patch1609: kvm-vmdk-Create-streamOptimized-as-version-3.patch
3277
+ # For bz#1299116 - qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)"
3278
+ Patch1610: kvm-vmdk-Fix-converting-to-streamOptimized.patch
3279
+ # For bz#1299116 - qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)"
3280
+ Patch1611: kvm-vmdk-Fix-calculation-of-block-status-s-offset.patch
3281
+ # For bz#1312289 - "qemu-kvm: /builddir/build/BUILD/qemu-1.5.3/hw/scsi/virtio-scsi.c:533: virtio_scsi_push_event: Assertion `event == 0' failed" after hotplug 20 virtio-scsi disks then hotunplug them
3282
+ Patch1612: kvm-virtio-scsi-Prevent-assertion-on-missed-events.patch
3283
+ # For bz#1177318 - Guest using rbd based image as disk failed to start when sandbox was enabled
3284
+ Patch1613: kvm-seccomp-adding-sysinfo-system-call-to-whitelist.patch
3285
+ # For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
3286
+ Patch1614: kvm-acpi-strip-compiler-info-in-built-in-DSDT.patch
3287
+ # For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
3288
+ Patch1615: kvm-acpi-fix-endian-ness-for-table-ids.patch
3289
+ # For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
3290
+ Patch1616: kvm-acpi-support-specified-oem-table-id-for-build_header.patch
3291
+ # For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
3292
+ Patch1617: kvm-acpi-take-oem_id-in-build_header-optionally.patch
3293
+ # For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
3294
+ Patch1618: kvm-acpi-expose-oem_id-and-oem_table_id-in-build_rsdt.patch
3295
+ # For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
3296
+ Patch1619: kvm-acpi-add-function-to-extract-oem_id-and-oem_table_id.patch
3297
+ # For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
3298
+ Patch1620: kvm-pc-set-the-OEM-fields-in-the-RSDT-and-the-FADT-from-.patch
3299
+ # For bz#1156635 - Libvirt is confused that qemu-kvm exposes 'block-job-cancel' but not 'block-stream'
3300
+ Patch1621: kvm-block-jobs-qemu-kvm-rhel-differentiation.patch
3301
+ # For bz#1283198 - RFE: backport max monitor limitation from Qemu upstream
3302
+ Patch1622: kvm-qxl-allow-to-specify-head-limit-to-qxl-driver.patch
3303
+ # For bz#1283198 - RFE: backport max monitor limitation from Qemu upstream
3304
+ Patch1623: kvm-qxl-Fix-new-function-name-for-spice-server-library.patch
3305
+ # For bz#1268345 - posix_fallocate emulation on NFS fails with Bad file descriptor if fd is opened O_WRONLY
3306
+ Patch1624: kvm-block-raw-posix-Open-file-descriptor-O_RDWR-to-work-.patch
3307
+ # For bz#1256741 - "CapsLock" will work as "\" when boot a guest with usb-kbd
3308
+ Patch1625: kvm-hw-input-hid.c-Fix-capslock-hid-code.patch
3309
+ # For bz#1340971 - qemu: accel=tcg does not implement SSE 4 properly
3310
+ Patch1626: kvm-target-i386-fix-pcmpxstrx-equal-ordered-strstr-mode.patch
3311
+ # For bz#1336491 - Ship FD connection patches qemu-kvm part
3312
+ Patch1627: kvm-spice-do-not-require-TCP-ports.patch
3313
+ # For bz#1346982 - Regression from CVE-2016-3712: windows installer fails to start
3314
+ Patch1628: kvm-vga-add-sr_vbe-register-set.patch
3315
+ # For bz#1340929 - CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.3]
3316
+ Patch1629: kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch
3317
+ # For bz#1327599 - Add Skylake CPU model
3318
+ Patch1630: kvm-target-i386-add-feature-flags-for-CPUID-EAX-0xd-ECX-.patch
3319
+ # For bz#1327599 - Add Skylake CPU model
3320
+ Patch1631: kvm-target-i386-add-Skylake-Client-cpu-model.patch
3321
+ # For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
3322
+ Patch1632: kvm-util-introduce-MIN_NON_ZERO.patch
3323
+ # For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
3324
+ Patch1633: kvm-BlockLimits-introduce-max_transfer_length.patch
3325
+ # For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
3326
+ Patch1634: kvm-block-backend-expose-bs-bl.max_transfer_length.patch
3327
+ # For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
3328
+ Patch1635: kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch
3329
+ # For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
3330
+ Patch1636: kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch
3331
+ # For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
3332
+ Patch1637: kvm-scsi-Advertise-limits-by-blocksize-not-512.patch
3333
+ # For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
3334
+ Patch1638: kvm-util-Fix-MIN_NON_ZERO.patch
3335
+ # For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
3336
+ Patch1639: kvm-qxl-factor-out-qxl_get_check_slot_offset.patch
3337
+ # For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
3338
+ Patch1640: kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch
3339
+ # For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
3340
+ Patch1641: kvm-qxl-fix-surface-migration.patch
3341
+ # For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
3342
+ Patch1642: kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch
3343
+ # For bz#1359729 - CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.3]
3344
+ Patch1643: kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch
3345
+ # For bz#1276036 - Crash on QMP input exceeding limits
3346
+ Patch1644: kvm-json-parser-drop-superfluous-assignment-for-token-va.patch
3347
+ # For bz#1276036 - Crash on QMP input exceeding limits
3348
+ Patch1645: kvm-qjson-Apply-nesting-limit-more-sanely.patch
3349
+ # For bz#1276036 - Crash on QMP input exceeding limits
3350
+ Patch1646: kvm-qjson-Don-t-crash-when-input-exceeds-nesting-limit.patch
3351
+ # For bz#1276036 - Crash on QMP input exceeding limits
3352
+ Patch1647: kvm-check-qjson-Add-test-for-JSON-nesting-depth-limit.patch
3353
+ # For bz#1276036 - Crash on QMP input exceeding limits
3354
+ Patch1648: kvm-qjson-Spell-out-some-silent-assumptions.patch
3355
+ # For bz#1276036 - Crash on QMP input exceeding limits
3356
+ Patch1649: kvm-qjson-Give-each-of-the-six-structural-chars-its-own-.patch
3357
+ # For bz#1276036 - Crash on QMP input exceeding limits
3358
+ Patch1650: kvm-qjson-Inline-token_is_keyword-and-simplify.patch
3359
+ # For bz#1276036 - Crash on QMP input exceeding limits
3360
+ Patch1651: kvm-qjson-Inline-token_is_escape-and-simplify.patch
3361
+ # For bz#1276036 - Crash on QMP input exceeding limits
3362
+ Patch1652: kvm-qjson-replace-QString-in-JSONLexer-with-GString.patch
3363
+ # For bz#1276036 - Crash on QMP input exceeding limits
3364
+ Patch1653: kvm-qjson-Convert-to-parser-to-recursive-descent.patch
3365
+ # For bz#1276036 - Crash on QMP input exceeding limits
3366
+ Patch1654: kvm-qjson-store-tokens-in-a-GQueue.patch
3367
+ # For bz#1276036 - Crash on QMP input exceeding limits
3368
+ Patch1655: kvm-qjson-surprise-allocating-6-QObjects-per-token-is-ex.patch
3369
+ # For bz#1276036 - Crash on QMP input exceeding limits
3370
+ Patch1656: kvm-qjson-Limit-number-of-tokens-in-addition-to-total-si.patch
3371
+ # For bz#1276036 - Crash on QMP input exceeding limits
3372
+ Patch1657: kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch
3373
+ # For bz#1276036 - Crash on QMP input exceeding limits
3374
+ Patch1658: kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch
3375
+ # For bz#1360137 - GLib-WARNING **: gmem.c:482: custom memory allocation vtable not supported
3376
+ Patch1659: kvm-trace-remove-malloc-tracing.patch
3377
+ # For bz#1367040 - QEMU crash when guest notifies non-existent virtqueue
3378
+ Patch1660: kvm-virtio-validate-the-existence-of-handle_output-befor.patch
3379
+ # For bz#1371619 - Flags xsaveopt xsavec xgetbv1 are missing on qemu-kvm
3380
+ Patch1661: kvm-Fix-backport-of-target-i386-add-feature-flags-for-CP.patch
3381
+ # For bz#1373088 - [FJ7.3 Bug]: virsh dump with both --memory-only and --format option fails
3382
+ Patch1662: kvm-Add-skip_dump-flag-to-ignore-memory-region-during-du.patch
3383
+ # For bz#1372459 - [Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl) (qemu-kvm)
3384
+ Patch1663: kvm-target-i386-Add-support-for-FEAT_7_0_ECX.patch
3385
+ # For bz#1372459 - [Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl) (qemu-kvm)
3386
+ Patch1664: kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch
3387
+ # For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
3388
+ Patch1665: kvm-nbd-server-Set-O_NONBLOCK-on-client-fd.patch
3389
+ # For bz#1376542 - RHSA-2016-1756 breaks migration of instances
3390
+ Patch1666: kvm-virtio-recalculate-vq-inuse-after-migration.patch
3190
3391
3191
3392
3192
3393
BuildRequires: zlib-devel
@@ -3366,37 +3567,6 @@ This package contains some diagnostics and debugging tools for KVM,
3366
3567
such as kvm_stat.
3367
3568
%endif
3368
3569
3369
- %package -n libcacard%{?pkgsuffix}
3370
- Summary: Common Access Card (CAC) Emulation
3371
- Group: Development/Libraries
3372
-
3373
- %rhel_rhev_conflicts libcacard
3374
-
3375
- %description -n libcacard%{?pkgsuffix}
3376
- Common Access Card (CAC) emulation library.
3377
-
3378
- %package -n libcacard-tools%{?pkgsuffix}
3379
- Summary: CAC Emulation tools
3380
- Group: Development/Libraries
3381
- Requires: libcacard = %{epoch}:%{version}-%{release}
3382
- # older qemu-img has vscclient which is now in libcacard-tools
3383
- Requires: qemu-img >= 3:1.3.0-5
3384
-
3385
- %rhel_rhev_conflicts libcacard-tools
3386
-
3387
- %description -n libcacard-tools%{?pkgsuffix}
3388
- CAC emulation tools.
3389
-
3390
- %package -n libcacard-devel%{?pkgsuffix}
3391
- Summary: CAC Emulation devel
3392
- Group: Development/Libraries
3393
- Requires: libcacard = %{epoch}:%{version}-%{release}
3394
-
3395
- %rhel_rhev_conflicts libcacard-devel
3396
-
3397
- %description -n libcacard-devel%{?pkgsuffix}
3398
- CAC emulation development files.
3399
-
3400
3570
%prep
3401
3571
%setup -q -n qemu-%{version}
3402
3572
cp %{SOURCE18} pc-bios # keep "make check" happy
@@ -4966,6 +5136,106 @@ cp %{SOURCE18} pc-bios # keep "make check" happy
4966
5136
%patch1564 -p1
4967
5137
%patch1565 -p1
4968
5138
%patch1566 -p1
5139
+ %patch1567 -p1
5140
+ %patch1568 -p1
5141
+ %patch1569 -p1
5142
+ %patch1570 -p1
5143
+ %patch1571 -p1
5144
+ %patch1572 -p1
5145
+ %patch1573 -p1
5146
+ %patch1574 -p1
5147
+ %patch1575 -p1
5148
+ %patch1576 -p1
5149
+ %patch1577 -p1
5150
+ %patch1578 -p1
5151
+ %patch1579 -p1
5152
+ %patch1580 -p1
5153
+ %patch1581 -p1
5154
+ %patch1582 -p1
5155
+ %patch1583 -p1
5156
+ %patch1584 -p1
5157
+ %patch1585 -p1
5158
+ %patch1586 -p1
5159
+ %patch1587 -p1
5160
+ %patch1588 -p1
5161
+ %patch1589 -p1
5162
+ %patch1590 -p1
5163
+ %patch1591 -p1
5164
+ %patch1592 -p1
5165
+ %patch1593 -p1
5166
+ %patch1594 -p1
5167
+ %patch1595 -p1
5168
+ %patch1596 -p1
5169
+ %patch1597 -p1
5170
+ %patch1598 -p1
5171
+ %patch1599 -p1
5172
+ %patch1600 -p1
5173
+ %patch1601 -p1
5174
+ %patch1602 -p1
5175
+ %patch1603 -p1
5176
+ %patch1604 -p1
5177
+ %patch1605 -p1
5178
+ %patch1606 -p1
5179
+ %patch1607 -p1
5180
+ %patch1608 -p1
5181
+ %patch1609 -p1
5182
+ %patch1610 -p1
5183
+ %patch1611 -p1
5184
+ %patch1612 -p1
5185
+ %patch1613 -p1
5186
+ %patch1614 -p1
5187
+ %patch1615 -p1
5188
+ %patch1616 -p1
5189
+ %patch1617 -p1
5190
+ %patch1618 -p1
5191
+ %patch1619 -p1
5192
+ %patch1620 -p1
5193
+ %patch1621 -p1
5194
+ %patch1622 -p1
5195
+ %patch1623 -p1
5196
+ %patch1624 -p1
5197
+ %patch1625 -p1
5198
+ %patch1626 -p1
5199
+ %patch1627 -p1
5200
+ %patch1628 -p1
5201
+ %patch1629 -p1
5202
+ %patch1630 -p1
5203
+ %patch1631 -p1
5204
+ %patch1632 -p1
5205
+ %patch1633 -p1
5206
+ %patch1634 -p1
5207
+ %patch1635 -p1
5208
+ %patch1636 -p1
5209
+ %patch1637 -p1
5210
+ %patch1638 -p1
5211
+ %patch1639 -p1
5212
+ %patch1640 -p1
5213
+ %patch1641 -p1
5214
+ %patch1642 -p1
5215
+ %patch1643 -p1
5216
+ %patch1644 -p1
5217
+ %patch1645 -p1
5218
+ %patch1646 -p1
5219
+ %patch1647 -p1
5220
+ %patch1648 -p1
5221
+ %patch1649 -p1
5222
+ %patch1650 -p1
5223
+ %patch1651 -p1
5224
+ %patch1652 -p1
5225
+ %patch1653 -p1
5226
+ %patch1654 -p1
5227
+ %patch1655 -p1
5228
+ %patch1656 -p1
5229
+ %patch1657 -p1
5230
+ %patch1658 -p1
5231
+ %patch1659 -p1
5232
+ %patch1660 -p1
5233
+ %patch1661 -p1
5234
+ %patch1662 -p1
5235
+ %patch1663 -p1
5236
+ %patch1664 -p1
5237
+ %patch1665 -p1
5238
+ %patch1666 -p1
4969
5239
4970
5240
%build
4971
5241
buildarch="%{kvm_target}-softmmu"
@@ -5065,8 +5335,6 @@ dobuild() {
5065
5335
--disable-guest-agent \
5066
5336
"$@"
5067
5337
5068
- make libcacard.la %{?_smp_mflags} $buildldflags
5069
- make vscclient %{?_smp_mflags} $buildldflags
5070
5338
make qemu-img %{?_smp_mflags} $buildldflags
5071
5339
make qemu-io %{?_smp_mflags} $buildldflags
5072
5340
make qemu-nbd %{?_smp_mflags} $buildldflags
@@ -5215,6 +5483,12 @@ dobuild --target-list="$buildarch"
5215
5483
rom_link ../sgabios/sgabios.bin sgabios.bin
5216
5484
%endif
5217
5485
5486
+ # Remove libcacard
5487
+ rm -rf $RPM_BUILD_ROOT%{_bindir}/vscclient
5488
+ rm -rf $RPM_BUILD_ROOT%{_includedir}/cacard
5489
+ rm -rf $RPM_BUILD_ROOT%{_libdir}/libcacard.so*
5490
+ rm -rf $RPM_BUILD_ROOT%{_libdir}/pkgconfig/libcacard.pc
5491
+
5218
5492
%if %{with guest_agent}
5219
5493
# For the qemu-guest-agent subpackage, install:
5220
5494
# - the systemd service file and the udev rules:
@@ -5250,8 +5524,6 @@ dobuild --target-list="$buildarch"
5250
5524
install -m 0644 %{SOURCE12} $RPM_BUILD_ROOT%{_sysconfdir}/%{pkgname}
5251
5525
%endif
5252
5526
5253
- make %{?_smp_mflags} $buildldflags DESTDIR=$RPM_BUILD_ROOT install-libcacard
5254
- find $RPM_BUILD_ROOT -name "libcacard.so*" -exec chmod +x \{\} \;
5255
5527
5256
5528
find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f
5257
5529
@@ -5259,7 +5531,6 @@ find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f
5259
5531
mkdir -p $RPM_BUILD_ROOT%{_bindir}
5260
5532
mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1/*
5261
5533
mkdir -p $RPM_BUILD_ROOT%{_mandir}/man8/*
5262
- libtool --mode=install install -m 0755 vscclient $RPM_BUILD_ROOT%{_bindir}/vscclient
5263
5534
install -m 0755 qemu-img $RPM_BUILD_ROOT%{_bindir}/qemu-img
5264
5535
install -m 0755 qemu-io $RPM_BUILD_ROOT%{_bindir}/qemu-io
5265
5536
install -m 0755 qemu-nbd $RPM_BUILD_ROOT%{_bindir}/qemu-nbd
@@ -5280,6 +5551,7 @@ find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f
5280
5551
%post
5281
5552
# load kvm modules now, so we can make sure no reboot is needed.
5282
5553
# If there's already a kvm module installed, we don't mess with it
5554
+ %udev_rules_update
5283
5555
sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || :
5284
5556
udevadm trigger --subsystem-match=misc --sysname-match=kvm --action=add || :
5285
5557
@@ -5407,60 +5679,241 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || :
5407
5679
%{_mandir}/man1/qemu-img.1*
5408
5680
%{_mandir}/man8/qemu-nbd.8*
5409
5681
5410
- %files -n libcacard%{?pkgsuffix}
5411
- %defattr(-,root,root,-)
5412
- %{_libdir}/libcacard.so.*
5413
-
5414
- %files -n libcacard-tools%{?pkgsuffix}
5415
- %defattr(-,root,root,-)
5416
- %{_bindir}/vscclient
5417
-
5418
- %files -n libcacard-devel%{?pkgsuffix}
5419
- %defattr(-,root,root,-)
5420
- %{_includedir}/cacard
5421
- %{_libdir}/libcacard.so
5422
- %{_libdir}/pkgconfig/libcacard.pc
5423
-
5424
5682
%changelog
5425
- * Tue Aug 02 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.7
5426
- - kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch [bz#1358996]
5427
- - Resolves: bz#1358996
5428
- (CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.2.z])
5429
-
5430
- * Wed Jul 27 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.6
5431
- - kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch [bz#1359728]
5432
- - Resolves: bz#1359728
5433
- (EMBARGOED CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.2.z])
5434
-
5435
- * Fri Jul 01 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.5
5436
- - kvm-vga-add-sr_vbe-register-set.patch [bz#1347527]
5437
- - Resolves: bz#1347527
5683
+ * Tue Sep 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-126.el7
5684
+ - kvm-virtio-recalculate-vq-inuse-after-migration.patch [bz#1376542]
5685
+ - Resolves: bz#1376542
5686
+ (RHSA-2016-1756 breaks migration of instances)
5687
+
5688
+ * Thu Sep 15 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-125.el7
5689
+ - kvm-nbd-server-Set-O_NONBLOCK-on-client-fd.patch [bz#1285453]
5690
+ - Resolves: bz#1285453
5691
+ (An NBD client can cause QEMU main loop to block when connecting to built-in NBD server)
5692
+
5693
+ * Tue Sep 13 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-124.el7
5694
+ - kvm-target-i386-Add-support-for-FEAT_7_0_ECX.patch [bz#1372459]
5695
+ - kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch [bz#1372459]
5696
+ - Resolves: bz#1372459
5697
+ ([Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl) (qemu-kvm))
5698
+
5699
+ * Fri Sep 09 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-123.el7
5700
+ - kvm-Fix-backport-of-target-i386-add-feature-flags-for-CP.patch [bz#1371619]
5701
+ - kvm-Add-skip_dump-flag-to-ignore-memory-region-during-du.patch [bz#1373088]
5702
+ - Resolves: bz#1371619
5703
+ (Flags xsaveopt xsavec xgetbv1 are missing on qemu-kvm)
5704
+ - Resolves: bz#1373088
5705
+ ([FJ7.3 Bug]: virsh dump with both --memory-only and --format option fails)
5706
+
5707
+ * Fri Aug 26 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-122.el7
5708
+ - kvm-virtio-validate-the-existence-of-handle_output-befor.patch [bz#1367040]
5709
+ - Resolves: bz#1367040
5710
+ (QEMU crash when guest notifies non-existent virtqueue)
5711
+
5712
+ * Tue Aug 02 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-121.el7
5713
+ - kvm-json-parser-drop-superfluous-assignment-for-token-va.patch [bz#1276036]
5714
+ - kvm-qjson-Apply-nesting-limit-more-sanely.patch [bz#1276036]
5715
+ - kvm-qjson-Don-t-crash-when-input-exceeds-nesting-limit.patch [bz#1276036]
5716
+ - kvm-check-qjson-Add-test-for-JSON-nesting-depth-limit.patch [bz#1276036]
5717
+ - kvm-qjson-Spell-out-some-silent-assumptions.patch [bz#1276036]
5718
+ - kvm-qjson-Give-each-of-the-six-structural-chars-its-own-.patch [bz#1276036]
5719
+ - kvm-qjson-Inline-token_is_keyword-and-simplify.patch [bz#1276036]
5720
+ - kvm-qjson-Inline-token_is_escape-and-simplify.patch [bz#1276036]
5721
+ - kvm-qjson-replace-QString-in-JSONLexer-with-GString.patch [bz#1276036]
5722
+ - kvm-qjson-Convert-to-parser-to-recursive-descent.patch [bz#1276036]
5723
+ - kvm-qjson-store-tokens-in-a-GQueue.patch [bz#1276036]
5724
+ - kvm-qjson-surprise-allocating-6-QObjects-per-token-is-ex.patch [bz#1276036]
5725
+ - kvm-qjson-Limit-number-of-tokens-in-addition-to-total-si.patch [bz#1276036]
5726
+ - kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch [bz#1276036]
5727
+ - kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch [bz#1276036]
5728
+ - kvm-trace-remove-malloc-tracing.patch [bz#1360137]
5729
+ - Resolves: bz#1276036
5730
+ (Crash on QMP input exceeding limits)
5731
+ - Resolves: bz#1360137
5732
+ (GLib-WARNING **: gmem.c:482: custom memory allocation vtable not supported)
5733
+
5734
+ * Fri Jul 29 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-120.el7
5735
+ - kvm-Add-install-dependency-to-newer-libusbx-version.patch [bz#1351106]
5736
+ - kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch [bz#1359729]
5737
+ - Resolves: bz#1351106
5738
+ (symbol lookup error: /usr/libexec/qemu-kvm: undefined symbol: libusb_get_port_numbers)
5739
+ - Resolves: bz#1359729
5740
+ (CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.3])
5741
+
5742
+ * Tue Jul 26 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-119.el7
5743
+ - kvm-qxl-factor-out-qxl_get_check_slot_offset.patch [bz#1355730]
5744
+ - kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch [bz#1355730]
5745
+ - kvm-qxl-fix-surface-migration.patch [bz#1355730]
5746
+ - kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch [bz#1355730]
5747
+ - Resolves: bz#1355730
5748
+ (spice-gtk shows outdated screen state after migration [qemu-kvm])
5749
+
5750
+ * Tue Jul 19 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-118.el7
5751
+ - kvm-util-introduce-MIN_NON_ZERO.patch [bz#1318199]
5752
+ - kvm-BlockLimits-introduce-max_transfer_length.patch [bz#1318199]
5753
+ - kvm-block-backend-expose-bs-bl.max_transfer_length.patch [bz#1318199]
5754
+ - kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch [bz#1318199]
5755
+ - kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch [bz#1318199]
5756
+ - kvm-scsi-Advertise-limits-by-blocksize-not-512.patch [bz#1318199]
5757
+ - kvm-util-Fix-MIN_NON_ZERO.patch [bz#1318199]
5758
+ - Resolves: bz#1318199
5759
+ (expose host BLKSECTGET limit in scsi-block (qemu-kvm))
5760
+
5761
+ * Tue Jul 12 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-117.el7
5762
+ - kvm-target-i386-add-feature-flags-for-CPUID-EAX-0xd-ECX-.patch [bz#1327599]
5763
+ - kvm-target-i386-add-Skylake-Client-cpu-model.patch [bz#1327599]
5764
+ - Resolves: bz#1327599
5765
+ (Add Skylake CPU model)
5766
+
5767
+ * Tue Jun 28 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-116.el7
5768
+ - kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch [bz#1340929]
5769
+ - Resolves: bz#1340929
5770
+ (CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.3])
5771
+
5772
+ * Mon Jun 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-115.el7
5773
+ - kvm-spice-do-not-require-TCP-ports.patch [bz#1336491]
5774
+ - kvm-vga-add-sr_vbe-register-set.patch [bz#1346982]
5775
+ - Resolves: bz#1336491
5776
+ (Ship FD connection patches qemu-kvm part)
5777
+ - Resolves: bz#1346982
5438
5778
(Regression from CVE-2016-3712: windows installer fails to start)
5439
5779
5440
- * Tue May 03 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.4
5441
- - kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch [bz#1331412]
5442
- - kvm-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch [bz#1331412]
5443
- - kvm-vga-add-vbe_enabled-helper.patch [bz#1331412]
5444
- - kvm-vga-factor-out-vga-register-setup.patch [bz#1331412]
5445
- - kvm-vga-update-vga-register-setup-on-vbe-changes.patch [bz#1331412]
5446
- - kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch [bz#1331412]
5447
- - Resolves: bz#1331412
5448
- (EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z])
5449
-
5450
- * Thu Jan 21 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.3
5451
- - kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch [bz#1298047]
5452
- - Resolves: bz#1298047
5453
- (CVE-2016-1714 qemu-kvm: Qemu: nvram: OOB r/w access in processing firmware configurations [rhel-7.2.z])
5454
-
5455
- * Wed Jan 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.2
5456
- - kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch [bz#1298828]
5457
- - Resolves: bz#1298828
5780
+ * Wed Jun 15 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-114.el7
5781
+ - kvm-hw-input-hid.c-Fix-capslock-hid-code.patch [bz#1256741]
5782
+ - kvm-target-i386-fix-pcmpxstrx-equal-ordered-strstr-mode.patch [bz#1340971]
5783
+ - kvm-spec-Update-rules-before-triggering-for-kvm-device.patch [bz#1333159]
5784
+ - Resolves: bz#1256741
5785
+ ("CapsLock" will work as "\" when boot a guest with usb-kbd)
5786
+ - Resolves: bz#1333159
5787
+ (qemu-kvm doesn't reload udev rules before triggering for kvm device)
5788
+ - Resolves: bz#1340971
5789
+ (qemu: accel=tcg does not implement SSE 4 properly)
5790
+
5791
+ * Sat May 28 2016 Jeff E. Nelson <jen@redhat.com> - 1.5.3-113.el7
5792
+ - kvm-qxl-allow-to-specify-head-limit-to-qxl-driver.patch [bz#1283198]
5793
+ - kvm-qxl-Fix-new-function-name-for-spice-server-library.patch [bz#1283198]
5794
+ - kvm-block-raw-posix-Open-file-descriptor-O_RDWR-to-work-.patch [bz#1268345]
5795
+ - Resolves: bz#1268345
5796
+ (posix_fallocate emulation on NFS fails with Bad file descriptor if fd is opened O_WRONLY)
5797
+ - Resolves: bz#1283198
5798
+ (RFE: backport max monitor limitation from Qemu upstream)
5799
+
5800
+ * Mon May 16 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-112.el7
5801
+ - kvm-virtio-scsi-Prevent-assertion-on-missed-events.patch [bz#1312289]
5802
+ - kvm-seccomp-adding-sysinfo-system-call-to-whitelist.patch [bz#1177318]
5803
+ - kvm-acpi-strip-compiler-info-in-built-in-DSDT.patch [bz#1330969]
5804
+ - kvm-acpi-fix-endian-ness-for-table-ids.patch [bz#1330969]
5805
+ - kvm-acpi-support-specified-oem-table-id-for-build_header.patch [bz#1330969]
5806
+ - kvm-acpi-take-oem_id-in-build_header-optionally.patch [bz#1330969]
5807
+ - kvm-acpi-expose-oem_id-and-oem_table_id-in-build_rsdt.patch [bz#1330969]
5808
+ - kvm-acpi-add-function-to-extract-oem_id-and-oem_table_id.patch [bz#1330969]
5809
+ - kvm-pc-set-the-OEM-fields-in-the-RSDT-and-the-FADT-from-.patch [bz#1330969]
5810
+ - kvm-block-jobs-qemu-kvm-rhel-differentiation.patch [bz#1156635]
5811
+ - Resolves: bz#1156635
5812
+ (Libvirt is confused that qemu-kvm exposes 'block-job-cancel' but not 'block-stream')
5813
+ - Resolves: bz#1177318
5814
+ (Guest using rbd based image as disk failed to start when sandbox was enabled)
5815
+ - Resolves: bz#1312289
5816
+ ("qemu-kvm: /builddir/build/BUILD/qemu-1.5.3/hw/scsi/virtio-scsi.c:533: virtio_scsi_push_event: Assertion `event == 0' failed" after hotplug 20 virtio-scsi disks then hotunplug them)
5817
+ - Resolves: bz#1330969
5818
+ (match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC)
5819
+
5820
+ * Thu May 05 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-111.el7
5821
+ - kvm-vmdk-Leave-bdi-intact-if-ENOTSUP-in-vmdk_get_info.patch [bz#1299250]
5822
+ - kvm-vmdk-Use-g_random_int-to-generate-CID.patch [bz#1299250]
5823
+ - kvm-vmdk-Fix-comment-to-match-code-of-extent-lines.patch [bz#1299250]
5824
+ - kvm-vmdk-Clean-up-descriptor-file-reading.patch [bz#1299250]
5825
+ - kvm-vmdk-Check-descriptor-file-length-when-reading-it.patch [bz#1299250]
5826
+ - kvm-vmdk-Remove-unnecessary-initialization.patch [bz#1299250]
5827
+ - kvm-vmdk-Set-errp-on-failures-in-vmdk_open_vmdk4.patch [bz#1299250]
5828
+ - kvm-block-vmdk-make-ret-variable-usage-clear.patch [bz#1299250]
5829
+ - kvm-block-vmdk-move-string-allocations-from-stack-to-the.patch [bz#1299250]
5830
+ - kvm-block-vmdk-fixed-sizeof-error.patch [bz#1299250]
5831
+ - kvm-vmdk-Widen-before-shifting-32-bit-header-field.patch [bz#1299250]
5832
+ - kvm-vmdk-Fix-next_cluster_sector-for-compressed-write.patch [bz#1299250]
5833
+ - kvm-vmdk-Fix-index_in_cluster-calculation-in-vmdk_co_get.patch [bz#1299250]
5834
+ - kvm-vmdk-Use-vmdk_find_index_in_cluster-everywhere.patch [bz#1299250]
5835
+ - kvm-vmdk-Fix-next_cluster_sector-for-compressed-write2.patch [bz#1299250]
5836
+ - kvm-vmdk-Create-streamOptimized-as-version-3.patch [bz#1299116]
5837
+ - kvm-vmdk-Fix-converting-to-streamOptimized.patch [bz#1299116]
5838
+ - kvm-vmdk-Fix-calculation-of-block-status-s-offset.patch [bz#1299116]
5839
+ - Resolves: bz#1299116
5840
+ (qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)")
5841
+ - Resolves: bz#1299250
5842
+ (qemu-img created VMDK images are unbootable)
5843
+
5844
+ * Wed May 04 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-110.el7
5845
+ - kvm-qemu-io-Remove-unused-args_command.patch [bz#1272523]
5846
+ - kvm-cutils-Support-P-and-E-suffixes-in-strtosz.patch [bz#1272523]
5847
+ - kvm-qemu-io-Make-cvtnum-a-wrapper-around-strtosz_suffix.patch [bz#1272523]
5848
+ - kvm-qemu-io-Handle-cvtnum-errors-in-alloc.patch [bz#1272523]
5849
+ - kvm-qemu-io-Don-t-use-global-bs-in-command-implementatio.patch [bz#1272523]
5850
+ - kvm-qemu-io-Split-off-commands-to-qemu-io-cmds.c.patch [bz#1272523]
5851
+ - kvm-qemu-io-Factor-out-qemuio_command.patch [bz#1272523]
5852
+ - kvm-qemu-io-Move-help-function.patch [bz#1272523]
5853
+ - kvm-qemu-io-Move-quit-function.patch [bz#1272523]
5854
+ - kvm-qemu-io-Move-qemu_strsep-to-cutils.c.patch [bz#1272523]
5855
+ - kvm-qemu-io-Move-functions-for-registering-and-running-c.patch [bz#1272523]
5856
+ - kvm-qemu-io-Move-command_loop-and-friends.patch [bz#1272523]
5857
+ - kvm-qemu-io-Move-remaining-helpers-from-cmd.c.patch [bz#1272523]
5858
+ - kvm-qemu-io-Interface-cleanup.patch [bz#1272523]
5859
+ - kvm-qemu-io-Use-the-qemu-version-for-V.patch [bz#1272523]
5860
+ - kvm-Make-qemu-io-commands-available-in-HMP.patch [bz#1272523]
5861
+ - kvm-blkdebug-Add-BLKDBG_FLUSH_TO_OS-DISK-events.patch [bz#1272523]
5862
+ - kvm-qemu-io-fix-cvtnum-lval-types.patch [bz#1272523]
5863
+ - kvm-qemu-io-Check-for-trailing-chars.patch [bz#1272523]
5864
+ - kvm-qemu-io-Correct-error-messages.patch [bz#1272523]
5865
+ - kvm-ide-test-fix-failure-for-test_flush.patch [bz#1272523]
5866
+ - kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch [bz#1331413]
5867
+ - kvm-vga-fix-banked-access-bounds-checking-CVE-2016-xxxx.patch [bz#1331413]
5868
+ - kvm-vga-add-vbe_enabled-helper.patch [bz#1331413]
5869
+ - kvm-vga-factor-out-vga-register-setup.patch [bz#1331413]
5870
+ - kvm-vga-update-vga-register-setup-on-vbe-changes.patch [bz#1331413]
5871
+ - kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch [bz#1331413]
5872
+ - Resolves: bz#1272523
5873
+ (qemu-kvm build failure race condition in tests/ide-test)
5874
+ - Resolves: bz#1331413
5875
+ (EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3])
5876
+
5877
+ * Mon Mar 14 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-109.el7
5878
+ - kvm-e1000-eliminate-infinite-loops-on-out-of-bounds-tran.patch [bz#1296044]
5879
+ - kvm-nbd-Always-call-close_fn-in-nbd_client_new.patch [bz#1285453]
5880
+ - kvm-nbd-server-Coroutine-based-negotiation.patch [bz#1285453]
5881
+ - kvm-nbd-client_close-on-error-in-nbd_co_client_start.patch [bz#1285453]
5882
+ - kvm-Remove-libcacard-build.patch [bz#1314153]
5883
+ - Resolves: bz#1285453
5884
+ (An NBD client can cause QEMU main loop to block when connecting to built-in NBD server)
5885
+ - Resolves: bz#1296044
5886
+ (qemu-kvm: insufficient loop termination conditions in start_xmit() and e1000_receive() [rhel-7.3])
5887
+ - Resolves: bz#1314153
5888
+ (Disable building of libcacard)
5889
+
5890
+ * Mon Feb 08 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-108.el7
5891
+ - kvm-net-Make-qmp_query_rx_filter-with-name-argument-more.patch [bz#1269738]
5892
+ - kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch [bz#1298048]
5893
+ - Resolves: bz#1269738
5894
+ (Vlan table display repeat four times in qmp when queues=4)
5895
+ - Resolves: bz#1298048
5896
+ (CVE-2016-1714 qemu-kvm: Qemu: nvram: OOB r/w access in processing firmware configurations [rhel-7.3])
5897
+
5898
+ * Wed Jan 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-107.el7
5899
+ - kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch [bz#1283116]
5900
+ - Resolves: bz#1283116
5458
5901
([abrt] qemu-img: get_block_status(): qemu-img killed by SIGABRT)
5459
5902
5460
- * Tue Nov 17 2015 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.1
5461
- - kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch [bz#1279389]
5462
- - kvm-rbd-fix-ceph-settings-precedence.patch [bz#1279389]
5463
- - Resolves: bz#1279389
5903
+ * Wed Jan 13 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-106.el7
5904
+ - kvm-ehci-clear-suspend-bit-on-detach.patch [bz#1268879]
5905
+ - kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch [bz#1277248]
5906
+ - kvm-rbd-fix-ceph-settings-precedence.patch [bz#1277248]
5907
+ - kvm-target-i386-get-put-MSR_TSC_AUX-across-reset-and-mig.patch [bz#1265427]
5908
+ - kvm-rtl8139-Fix-receive-buffer-overflow-check.patch [bz#1252757]
5909
+ - kvm-rtl8139-Do-not-consume-the-packet-during-overflow-in.patch [bz#1252757]
5910
+ - Resolves: bz#1252757
5911
+ ([RHEL-7.2-qmu-kvm] Package is 100% lost when ping from host to Win2012r2 guest with 64000 size)
5912
+ - Resolves: bz#1265427
5913
+ (contents of MSR_TSC_AUX are not migrated)
5914
+ - Resolves: bz#1268879
5915
+ (Camera stops work after remote-viewer re-connection [qemu-kvm])
5916
+ - Resolves: bz#1277248
5464
5917
(ceph.conf properties override qemu's command-line properties)
5465
5918
5466
5919
* Fri Oct 16 2015 Jeff E. Nelson <jen@redhat.com> - 1.5.3-105.el7