QEMU is a FAST! processor emulator
CentOS Sources
2014-10-20 91048cb91e8e1d1bb309e909a27ddb26e809233f
import qemu-kvm-1.5.3-60.el7_0.10
11 files added
1 files modified
1614 ■■■■■ changed files
SOURCES/kvm-block-add-__com.redhat_change-backing-file-qmp-comma.patch 124 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-add-backing-file-option-to-block-stream.patch 234 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-add-helper-function-to-determine-if-a-BDS-is-i.patch 74 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-extend-block-commit-to-accept-a-string-for-the.patch 294 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-scsi-disk-fix-bug-in-scsi_block_new_request-introduc.patch 46 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-spice-display-add-display-channel-id-to-the-debug-me.patch 144 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-spice-make-sure-we-don-t-overflow-ssd-buf.patch 90 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vbe-make-bochs-dispi-interface-return-the-correct-me.patch 92 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vbe-rework-sanity-checks.patch 247 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vmstate_xhci_event-bug-compat-with-RHEL-7.0-RHEL-onl.patch 144 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vmstate_xhci_event-fix-unterminated-field-list.patch 64 ●●●●● patch | view | raw | blame | history
SPECS/qemu-kvm.spec 61 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-add-__com.redhat_change-backing-file-qmp-comma.patch
New file
@@ -0,0 +1,124 @@
From ce7b70a0a59a571095a9bec614cce7b260c8c4fd Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Fri, 19 Sep 2014 03:18:59 +0200
Subject: [PATCH 4/4] block: add __com.redhat_change-backing-file qmp command
Message-id: <c7fc7cefc7588dca2d02b0cc0051cdbdadbf20ac.1411096194.git.jcody@redhat.com>
Patchwork-id: 61313
O-Subject: [PATCH qemu-kvm-rhev RHEL7.0.z 4/4] block: add __com.redhat_change-backing-file qmp command
Bugzilla: 1122925
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Upstream, the QAPI command 'change-backing-file' was added in a patch,
as part of a series that allowed libvirt to specify backing file
names in block-commit and block-stream.
This standalone QAPI (change-backing-file) is not currently in use by
libvirt, except as a witness that QEMU has the ability to change backing
files in block-commit and block-stream.
However, change-backing-file also relies on node-names functionality,
which is not present in RHEL7.0.  The backport of node-names would also
be fairly instrusive, especially for a command that is not going to be
used beyond verifying its presence.
This downstream patch adds __com.redhat_change-backing-file, which
accepts the same arguments as its upstream namesake.  However, no action
is performed, and the command always returns QERR_UNSUPPORTED.
This is not placed inside the RHEL/RHEV differentiation commands, as it
is not a live block operation (upstream or the dummy version), and
returns synchronously.
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 blockdev.c       |    8 ++++++++
 qapi-schema.json |   16 ++++++++++++++++
 qmp-commands.hx  |   22 ++++++++++++++++++++++
 3 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index c4fb129..ff0fe9d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1782,6 +1782,14 @@ void qmp_block_job_complete(const char *device, Error **errp)
     block_job_complete(job, errp);
 }
+void qmp___com_redhat_change_backing_file(const char *device,
+                                          const char *image_node_name,
+                                          const char *backing_file,
+                                          Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+}
+
 void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 {
     QmpOutputVisitor *ov = qmp_output_visitor_new();
diff --git a/qapi-schema.json b/qapi-schema.json
index e11b641..3a5a743 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1826,6 +1826,22 @@
   'data': {'command-line': 'str', '*cpu-index': 'int'},
   'returns': 'str' }
+##
+# @__com.redhat_change-backing-file
+#
+# This is a placeholder function, that exists as a witness for libvirt
+# that the ability to specify backing files in block-commit and block-stream
+# exists in this version of QEMU.
+#
+# It has the same argument requirements as the upstream 'change-backing-file',
+# but performs no action.
+#
+# Returns: NotSupported
+##
+{ 'command': '__com.redhat_change-backing-file',
+  'data': { 'device': 'str', 'image-node-name': 'str',
+            'backing-file': 'str' } }
+
 #_rhev-only CONFIG_LIVE_BLOCK_OPS
 ##
 # @block-commit
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 94f8671..a300d10 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1241,6 +1241,28 @@ EQMP
 #endif
     {
+        .name       = RFQDN_REDHAT "change-backing-file",
+        .args_type  = "device:s,image-node-name:s,backing-file:s",
+        .mhandler.cmd_new = qmp_marshal_input___com_redhat_change_backing_file,
+    },
+
+SQMP
+@__com.redhat_change-backing-file
+-------------------
+@__com.redhat_change-backing-file
+
+This is a placeholder function, that exists as a witness for libvirt
+that the ability to specify backing files block-commit and block-stream
+exists in this version of QEMU.
+
+It has the same argument requirements as the upstream 'change-backing-file',
+but performs no action.
+
+Returns: NotSupported
+
+EQMP
+
+    {
         .name       = "balloon",
         .args_type  = "value:M",
         .mhandler.cmd_new = qmp_marshal_input_balloon,
--
1.7.1
SOURCES/kvm-block-add-backing-file-option-to-block-stream.patch
New file
@@ -0,0 +1,234 @@
From dd7f33dff7cdf1d3481936560a1a1db285856eeb Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Fri, 19 Sep 2014 03:18:58 +0200
Subject: [PATCH 3/4] block: add backing-file option to block-stream
Message-id: <5b8611fab581db6b4c5eb31c998378090819268d.1411096194.git.jcody@redhat.com>
Patchwork-id: 61312
O-Subject: [PATCH qemu-kvm-rhev RHEL7.0.z 3/4] block: add backing-file option to block-stream
Bugzilla: 1122925
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
On some image chains, QEMU may not always be able to resolve the
filenames properly, when updating the backing file of an image
after a block job.
For instance, certain relative pathnames may fail, or drives may
have been specified originally by file descriptor (e.g. /dev/fd/???),
or a relative protocol pathname may have been used.
In these instances, QEMU may lack the information to be able to make
the correct choice, but the user or management layer most likely does
have that knowledge.
With this extension to the block-stream api, the user is able to change
the backing file of the active layer as part of the block-stream
operation.
This allows the change to be 'safe', in the sense that if the attempt
to write the active image metadata fails, then the block-stream
operation returns failure, without disrupting the guest.
If a backing file string is not specified in the command, the backing
file string to use is determined in the same manner as it was
previously.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 13d8cc515dfcf5574077f964332d34890c0101d0)
Conflicts:
    block/stream.c
    blockdev.c
    qapi/block-core.json
RHEL7 Notes:  Conflicts due to: surrounding context differences, and
                                and the qapi json not being split into
                                separate files like upstream.  Also
                                upstream used 1024 for local backing
                                file string size, and downstream we
                                already use PATH_MAX instead.
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/stream.c   |   11 +++++------
 blockdev.c       |   23 +++++++++++++++++++----
 hmp.c            |    2 +-
 qapi-schema.json |   19 +++++++++++++++++--
 qmp-commands.hx  |    2 +-
 5 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/block/stream.c b/block/stream.c
index 2a6f533..367120d 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -32,7 +32,7 @@ typedef struct StreamBlockJob {
     RateLimit limit;
     BlockDriverState *base;
     BlockdevOnError on_error;
-    char backing_file_id[PATH_MAX];
+    char *backing_file_str;
 } StreamBlockJob;
 static int coroutine_fn stream_populate(BlockDriverState *bs,
@@ -182,7 +182,7 @@ wait:
     if (!block_job_is_cancelled(&s->common) && sector_num == end && ret == 0) {
         const char *base_id = NULL, *base_fmt = NULL;
         if (base) {
-            base_id = s->backing_file_id;
+            base_id = s->backing_file_str;
             if (base->drv) {
                 base_fmt = base->drv->format_name;
             }
@@ -192,6 +192,7 @@ wait:
     }
     qemu_vfree(buf);
+    g_free(s->backing_file_str);
     block_job_completed(&s->common, ret);
 }
@@ -213,7 +214,7 @@ static const BlockJobDriver stream_job_driver = {
 };
 void stream_start(BlockDriverState *bs, BlockDriverState *base,
-                  const char *base_id, int64_t speed,
+                  const char *backing_file_str, int64_t speed,
                   BlockdevOnError on_error,
                   BlockDriverCompletionFunc *cb,
                   void *opaque, Error **errp)
@@ -233,9 +234,7 @@ void stream_start(BlockDriverState *bs, BlockDriverState *base,
     }
     s->base = base;
-    if (base_id) {
-        pstrcpy(s->backing_file_id, sizeof(s->backing_file_id), base_id);
-    }
+    s->backing_file_str = g_strdup(backing_file_str);
     s->on_error = on_error;
     s->common.co = qemu_coroutine_create(stream_run);
diff --git a/blockdev.c b/blockdev.c
index b22b42e..c4fb129 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1425,14 +1425,17 @@ static void block_job_cb(void *opaque, int ret)
     bdrv_put_ref_bh_schedule(bs);
 }
-void qmp_block_stream(const char *device, bool has_base,
-                      const char *base, bool has_speed, int64_t speed,
+void qmp_block_stream(const char *device,
+                      bool has_base, const char *base,
+                      bool has_backing_file, const char *backing_file,
+                      bool has_speed, int64_t speed,
                       bool has_on_error, BlockdevOnError on_error,
                       Error **errp)
 {
     BlockDriverState *bs;
     BlockDriverState *base_bs = NULL;
     Error *local_err = NULL;
+    const char *base_name = NULL;
     if (!has_on_error) {
         on_error = BLOCKDEV_ON_ERROR_REPORT;
@@ -1444,15 +1447,27 @@ void qmp_block_stream(const char *device, bool has_base,
         return;
     }
-    if (base) {
+    if (has_base) {
         base_bs = bdrv_find_backing_image(bs, base);
         if (base_bs == NULL) {
             error_set(errp, QERR_BASE_NOT_FOUND, base);
             return;
         }
+        base_name = base;
     }
-    stream_start(bs, base_bs, base, has_speed ? speed : 0,
+    /* if we are streaming the entire chain, the result will have no backing
+     * file, and specifying one is therefore an error */
+    if (base_bs == NULL && has_backing_file) {
+        error_setg(errp, "backing file specified, but streaming the "
+                         "entire chain");
+        return;
+    }
+
+    /* backing_file string overrides base bs filename */
+    base_name = has_backing_file ? backing_file : base_name;
+
+    stream_start(bs, base_bs, base_name, has_speed ? speed : 0,
                  on_error, block_job_cb, bs, &local_err);
     if (error_is_set(&local_err)) {
         error_propagate(errp, local_err);
diff --git a/hmp.c b/hmp.c
index 841929d..b723b26 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1046,7 +1046,7 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
     const char *base = qdict_get_try_str(qdict, "base");
     int64_t speed = qdict_get_try_int(qdict, "speed", 0);
-    qmp_block_stream(device, base != NULL, base,
+    qmp_block_stream(device, base != NULL, base, false, NULL,
                      qdict_haskey(qdict, "speed"), speed,
                      BLOCKDEV_ON_ERROR_REPORT, true, &error);
diff --git a/qapi-schema.json b/qapi-schema.json
index 100b059..e11b641 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2274,6 +2274,21 @@
 #
 # @base:   #optional the common backing file name
 #
+# @backing-file: #optional The backing file string to write into the active
+#                          layer. This filename is not validated.
+#
+#                          If a pathname string is such that it cannot be
+#                          resolved by QEMU, that means that subsequent QMP or
+#                          HMP commands must use node-names for the image in
+#                          question, as filename lookup methods will fail.
+#
+#                          If not specified, QEMU will automatically determine
+#                          the backing file string to use, or error out if there
+#                          is no obvious choice.  Care should be taken when
+#                          specifying the string, to specify a valid filename or
+#                          protocol.
+#                          (Since 2.1)
+#
 # @speed:  #optional the maximum speed, in bytes per second
 #
 # @on-error: #optional the action to take on an error (default report).
@@ -2286,8 +2301,8 @@
 # Since: 1.1
 ##
 { 'command': 'block-stream',
-  'data': { 'device': 'str', '*base': 'str', '*speed': 'int',
-            '*on-error': 'BlockdevOnError' } }
+  'data': { 'device': 'str', '*base': 'str', '*backing-file': 'str',
+            '*speed': 'int', '*on-error': 'BlockdevOnError' } }
 #_end-rhev-only
 ##
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 79006c5..94f8671 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -999,7 +999,7 @@ EQMP
 #ifdef CONFIG_LIVE_BLOCK_OPS
     {
         .name       = "block-stream",
-        .args_type  = "device:B,base:s?,speed:o?,on-error:s?",
+        .args_type  = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
         .mhandler.cmd_new = qmp_marshal_input_block_stream,
     },
--
1.7.1
SOURCES/kvm-block-add-helper-function-to-determine-if-a-BDS-is-i.patch
New file
@@ -0,0 +1,74 @@
From 77785494f8bb202a99f895a1888ea6246ed81b2f Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Fri, 19 Sep 2014 03:18:56 +0200
Subject: [PATCH 1/4] block: add helper function to determine if a BDS is in a chain
Message-id: <aa9b5aa581c435e579e97bec44bb821e047b59f6.1411096194.git.jcody@redhat.com>
Patchwork-id: 61310
O-Subject: [PATCH qemu-kvm-rhev RHEL7.0.z 1/4] block: add helper function to determine if a BDS is in a chain
Bugzilla: 1122925
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
This is a small helper function, to determine if 'base' is in the
chain of BlockDriverState 'top'.  It returns true if it is in the chain,
and false otherwise.
If either argument is NULL, it will also return false.
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 5a6684d2b957f9ec75d7ed7b14332293abec1d6c)
Conflicts:
    block.c
    include/block/block.h
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c               |   11 +++++++++++
 include/block/block.h |    1 +
 2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/block.c b/block.c
index 4906f6b..058255d 100644
--- a/block.c
+++ b/block.c
@@ -3420,6 +3420,17 @@ BlockDriverState *bdrv_find(const char *name)
     return NULL;
 }
+/* If 'base' is in the same chain as 'top', return true. Otherwise,
+ * return false.  If either argument is NULL, return false. */
+bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base)
+{
+    while (top && top != base) {
+        top = top->backing_hd;
+    }
+
+    return top != NULL;
+}
+
 BlockDriverState *bdrv_next(BlockDriverState *bs)
 {
     if (!bs) {
diff --git a/include/block/block.h b/include/block/block.h
index 13ef173..972c0e7 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -361,6 +361,7 @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked);
 void bdrv_eject(BlockDriverState *bs, bool eject_flag);
 const char *bdrv_get_format_name(BlockDriverState *bs);
 BlockDriverState *bdrv_find(const char *name);
+bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
 BlockDriverState *bdrv_next(BlockDriverState *bs);
 void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
                   void *opaque);
--
1.7.1
SOURCES/kvm-block-extend-block-commit-to-accept-a-string-for-the.patch
New file
@@ -0,0 +1,294 @@
From c8dda202bd3faf6cdc91834586c8a42ff4a6f762 Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Fri, 19 Sep 2014 03:18:57 +0200
Subject: [PATCH 2/4] block: extend block-commit to accept a string for the backing file
Message-id: <d49dacc368c02a3cd3d3d9b1d7ea0dc75cc7884a.1411096194.git.jcody@redhat.com>
Patchwork-id: 61311
O-Subject: [PATCH qemu-kvm-rhev RHEL7.0.z 2/4] block: extend block-commit to accept a string for the backing file
Bugzilla: 1122925
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
On some image chains, QEMU may not always be able to resolve the
filenames properly, when updating the backing file of an image
after a block commit.
For instance, certain relative pathnames may fail, or drives may
have been specified originally by file descriptor (e.g. /dev/fd/???),
or a relative protocol pathname may have been used.
In these instances, QEMU may lack the information to be able to make
the correct choice, but the user or management layer most likely does
have that knowledge.
With this extension to the block-commit api, the user is able to change
the backing file of the overlay image as part of the block-commit
operation.
This allows the change to be 'safe', in the sense that if the attempt
to write the overlay image metadata fails, then the block-commit
operation returns failure, without disrupting the guest.
If the commit top is the active layer, then specifying the backing
file string will be treated as an error (there is no overlay image
to modify in that case).
If a backing file string is not specified in the command, the backing
file string to use is determined in the same manner as it was
previously.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 54e269009099cdc9483be115f1e12d56ad459c5e)
Conflicts:
    qapi/block-core.json
RHEL7 Notes: Conflict is due to qapi json being divided into separate
             files upstream; downstream in RHEL7 it is still in a single
             json file.
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block.c                   |    8 ++++++--
 block/commit.c            |    9 ++++++---
 blockdev.c                |    8 +++++++-
 include/block/block.h     |    3 ++-
 include/block/block_int.h |    3 ++-
 qapi-schema.json          |   20 ++++++++++++++++++--
 qmp-commands.hx           |   19 ++++++++++++++++++-
 7 files changed, 59 insertions(+), 11 deletions(-)
diff --git a/block.c b/block.c
index 058255d..d26e9aa 100644
--- a/block.c
+++ b/block.c
@@ -2319,12 +2319,15 @@ typedef struct BlkIntermediateStates {
  *
  * base <- active
  *
+ * If backing_file_str is non-NULL, it will be used when modifying top's
+ * overlay image metadata.
+ *
  * Error conditions:
  *  if active == top, that is considered an error
  *
  */
 int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
-                           BlockDriverState *base)
+                           BlockDriverState *base, const char *backing_file_str)
 {
     BlockDriverState *intermediate;
     BlockDriverState *base_bs = NULL;
@@ -2376,7 +2379,8 @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
     }
     /* success - we can delete the intermediate states, and link top->base */
-    ret = bdrv_change_backing_file(new_top_bs, base_bs->filename,
+    backing_file_str = backing_file_str ? backing_file_str : base_bs->filename;
+    ret = bdrv_change_backing_file(new_top_bs, backing_file_str,
                                    base_bs->drv ? base_bs->drv->format_name : "");
     if (ret) {
         goto exit;
diff --git a/block/commit.c b/block/commit.c
index e3e395d..b6e1770 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -37,6 +37,7 @@ typedef struct CommitBlockJob {
     BlockdevOnError on_error;
     int base_flags;
     int orig_overlay_flags;
+    char *backing_file_str;
 } CommitBlockJob;
 static int coroutine_fn commit_populate(BlockDriverState *bs,
@@ -141,7 +142,7 @@ wait:
     if (!block_job_is_cancelled(&s->common) && sector_num == end) {
         /* success */
-        ret = bdrv_drop_intermediate(active, top, base);
+        ret = bdrv_drop_intermediate(active, top, base, s->backing_file_str);
     }
 exit_free_buf:
@@ -158,7 +159,7 @@ exit_restore_reopen:
     if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
         bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
     }
-
+    g_free(s->backing_file_str);
     block_job_completed(&s->common, ret);
 }
@@ -182,7 +183,7 @@ static const BlockJobDriver commit_job_driver = {
 void commit_start(BlockDriverState *bs, BlockDriverState *base,
                   BlockDriverState *top, int64_t speed,
                   BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
-                  void *opaque, Error **errp)
+                  void *opaque, const char *backing_file_str, Error **errp)
 {
     CommitBlockJob *s;
     BlockReopenQueue *reopen_queue = NULL;
@@ -244,6 +245,8 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
     s->base_flags          = orig_base_flags;
     s->orig_overlay_flags  = orig_overlay_flags;
+    s->backing_file_str = g_strdup(backing_file_str);
+
     s->on_error = on_error;
     s->common.co = qemu_coroutine_create(commit_run);
diff --git a/blockdev.c b/blockdev.c
index a94c9d3..b22b42e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1465,6 +1465,7 @@ void qmp_block_stream(const char *device, bool has_base,
 void qmp_block_commit(const char *device,
                       bool has_base, const char *base,
                       bool has_top, const char *top,
+                      bool has_backing_file, const char *backing_file,
                       bool has_speed, int64_t speed,
                       Error **errp)
 {
@@ -1522,11 +1523,16 @@ void qmp_block_commit(const char *device,
     }
     if (top_bs == bs) {
+        if (has_backing_file) {
+            error_setg(errp, "'backing-file' specified,"
+                             " but 'top' is the active layer");
+            return;
+        }
         commit_active_start(bs, base_bs, speed, on_error, block_job_cb,
                             bs, &local_err);
     } else {
         commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,
-                    &local_err);
+                     has_backing_file ? backing_file : NULL, &local_err);
     }
     if (local_err != NULL) {
         error_propagate(errp, local_err);
diff --git a/include/block/block.h b/include/block/block.h
index 972c0e7..03b7960 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -256,7 +256,8 @@ int bdrv_change_backing_file(BlockDriverState *bs,
     const char *backing_file, const char *backing_fmt);
 void bdrv_register(BlockDriver *bdrv);
 int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
-                           BlockDriverState *base);
+                           BlockDriverState *base,
+                           const char *backing_file_str);
 BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
                                     BlockDriverState *bs);
 BlockDriverState *bdrv_find_base(BlockDriverState *bs);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 53fc98c..e6874b4 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -389,13 +389,14 @@ void stream_start(BlockDriverState *bs, BlockDriverState *base,
  * @on_error: The action to take upon error.
  * @cb: Completion function for the job.
  * @opaque: Opaque pointer value passed to @cb.
+ * @backing_file_str: String to use as the backing file in @top's overlay
  * @errp: Error object.
  *
  */
 void commit_start(BlockDriverState *bs, BlockDriverState *base,
                  BlockDriverState *top, int64_t speed,
                  BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
-                 void *opaque, Error **errp);
+                 void *opaque, const char *backing_file_str, Error **errp);
 /**
  * commit_active_start:
  * @bs: Active block device to be committed.
diff --git a/qapi-schema.json b/qapi-schema.json
index 3768872..100b059 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1842,6 +1842,23 @@
 #                    which contains the topmost data to be committed down. If
 #                    not specified, this is the active layer.
 #
+# @backing-file:  #optional The backing file string to write into the overlay
+#                           image of 'top'.  If 'top' is the active layer,
+#                           specifying a backing file string is an error. This
+#                           filename is not validated.
+#
+#                           If a pathname string is such that it cannot be
+#                           resolved by QEMU, that means that subsequent QMP or
+#                           HMP commands must use node-names for the image in
+#                           question, as filename lookup methods will fail.
+#
+#                           If not specified, QEMU will automatically determine
+#                           the backing file string to use, or error out if
+#                           there is no obvious choice. Care should be taken
+#                           when specifying the string, to specify a valid
+#                           filename or protocol.
+#                           (Since 2.1)
+#
 #                    If top == base, that is an error.
 #                    If top == active, the job will not be completed by itself,
 #                    user needs to complete the job with the block-job-complete
@@ -1854,7 +1871,6 @@
 #                    size of the smaller top, you can safely truncate it
 #                    yourself once the commit operation successfully completes.
 #
-#
 # @speed:  #optional the maximum speed, in bytes per second
 #
 # Returns: Nothing on success
@@ -1869,7 +1885,7 @@
 ##
 { 'command': 'block-commit',
   'data': { 'device': 'str', '*base': 'str', '*top': 'str',
-            '*speed': 'int' } }
+            '*backing-file': 'str', '*speed': 'int' } }
 ##
 # @drive-mirror
diff --git a/qmp-commands.hx b/qmp-commands.hx
index b6b6246..79006c5 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1005,7 +1005,7 @@ EQMP
     {
         .name       = "block-commit",
-        .args_type  = "device:B,base:s?,top:s?,speed:o?",
+        .args_type  = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
         .mhandler.cmd_new = qmp_marshal_input_block_commit,
     },
@@ -1026,6 +1026,23 @@ Arguments:
           which contains the topmost data to be committed down. If
           not specified, this is the active layer. (json-string, optional)
+- backing-file:     The backing file string to write into the overlay
+                    image of 'top'.  If 'top' is the active layer,
+                    specifying a backing file string is an error. This
+                    filename is not validated.
+
+                    If a pathname string is such that it cannot be
+                    resolved by QEMU, that means that subsequent QMP or
+                    HMP commands must use node-names for the image in
+                    question, as filename lookup methods will fail.
+
+                    If not specified, QEMU will automatically determine
+                    the backing file string to use, or error out if
+                    there is no obvious choice. Care should be taken
+                    when specifying the string, to specify a valid
+                    filename or protocol.
+                    (json-string, optional) (Since 2.1)
+
           If top == base, that is an error.
           If top == active, the job will not be completed by itself,
           user needs to complete the job with the block-job-complete
--
1.7.1
SOURCES/kvm-scsi-disk-fix-bug-in-scsi_block_new_request-introduc.patch
New file
@@ -0,0 +1,46 @@
From 0eae214c2b36ad2dd2b841c2dc97e1f86a8284c0 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 12 Sep 2014 11:56:30 +0200
Subject: [PATCH] scsi-disk: fix bug in scsi_block_new_request() introduced by commit 137745c
Message-id: <1410522991-11612-1-git-send-email-pbonzini@redhat.com>
Patchwork-id: 61021
O-Subject: [RHEL 7.1/7.0.z qemu-kvm PATCH] scsi-disk: fix bug in scsi_block_new_request() introduced by commit 137745c
Bugzilla: 1141189
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
From: Ulrich Obergfell <uobergfe@redhat.com>
This patch fixes a bug in scsi_block_new_request() that was introduced
by commit 137745c5c60f083ec982fe9e861e8c16ebca1ba8. If the host cache
is used - i.e. if BDRV_O_NOCACHE is _not_ set - the 'break' statement
needs to be executed to 'fall back' to SG_IO.
Cc: qemu-stable@nongnu.org
Signed-off-by: Ulrich Obergfell <uobergfe@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2fe5a9f73b3446690db2cae8a58473b0b4beaa32)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/scsi/scsi-disk.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 6491091..830e3bd 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2496,7 +2496,7 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
      * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without
      * O_DIRECT everything must go through SG_IO.
          */
-        if (bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE) {
+        if (!(bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE)) {
             break;
         }
--
1.7.1
SOURCES/kvm-spice-display-add-display-channel-id-to-the-debug-me.patch
New file
@@ -0,0 +1,144 @@
From 21a79d9dab61df3942c13df2a2472182abdb8a7f Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 15 Sep 2014 13:08:22 +0200
Subject: [PATCH 5/6] spice-display: add display channel id to the debug messages.
Message-id: <1410786503-19794-4-git-send-email-kraxel@redhat.com>
Patchwork-id: 61138
O-Subject: [RHEL-7.1 qemu-kvm PATCH 3/4] spice-display: add display channel id to the debug messages.
Bugzilla: 1139117
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
And s/__FUNCTION__/__func__/ while being at it.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 35b2122db446a03be9b88f540e865930efd01d6a)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 ui/spice-display.c |   27 ++++++++++++++-------------
 1 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 82d8b9f..da45282 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -297,7 +297,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
 {
     QXLDevMemSlot memslot;
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
     memset(&memslot, 0, sizeof(memslot));
     memslot.slot_group_id = MEMSLOT_GROUP_HOST;
@@ -311,7 +311,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
     memset(&surface, 0, sizeof(surface));
-    dprint(1, "%s: %dx%d\n", __FUNCTION__,
+    dprint(1, "%s/%d: %dx%d\n", __func__, ssd->qxl.id,
            surface_width(ssd->ds), surface_height(ssd->ds));
     surface.format     = SPICE_SURFACE_FMT_32_xRGB;
@@ -329,7 +329,7 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
 void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
 {
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
     qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
 }
@@ -354,7 +354,8 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
 {
     QXLRect update_area;
-    dprint(2, "%s: x %d y %d w %d h %d\n", __FUNCTION__, x, y, w, h);
+    dprint(2, "%s/%d: x %d y %d w %d h %d\n", __func__,
+           ssd->qxl.id, x, y, w, h);
     update_area.left = x,
     update_area.right = x + w;
     update_area.top = y;
@@ -371,7 +372,7 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
 {
     SimpleSpiceUpdate *update;
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
     memset(&ssd->dirty, 0, sizeof(ssd->dirty));
     if (ssd->surface) {
@@ -413,7 +414,7 @@ void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
 {
-    dprint(3, "%s:\n", __func__);
+    dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
     graphic_hw_update(ssd->dcl.con);
     qemu_mutex_lock(&ssd->lock);
@@ -427,7 +428,7 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
     if (ssd->notify) {
         ssd->notify = 0;
         qemu_spice_wakeup(ssd);
-        dprint(2, "%s: notify\n", __FUNCTION__);
+        dprint(2, "%s/%d: notify\n", __func__, ssd->qxl.id);
     }
 }
@@ -437,19 +438,19 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
 {
     SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
     ssd->worker = qxl_worker;
 }
 static void interface_set_compression_level(QXLInstance *sin, int level)
 {
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(1, "%s/%d:\n", __func__, sin->id);
     /* nothing to do */
 }
 static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
 {
-    dprint(3, "%s:\n", __FUNCTION__);
+    dprint(3, "%s/%d:\n", __func__, sin->id);
     /* nothing to do */
 }
@@ -472,7 +473,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
     SimpleSpiceUpdate *update;
     int ret = false;
-    dprint(3, "%s:\n", __FUNCTION__);
+    dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
     qemu_mutex_lock(&ssd->lock);
     update = QTAILQ_FIRST(&ssd->updates);
@@ -488,7 +489,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
 static int interface_req_cmd_notification(QXLInstance *sin)
 {
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(1, "%s/%d:\n", __func__, sin->id);
     return 1;
 }
@@ -498,7 +499,7 @@ static void interface_release_resource(QXLInstance *sin,
     SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
     uintptr_t id;
-    dprint(2, "%s:\n", __FUNCTION__);
+    dprint(2, "%s/%d:\n", __func__, ssd->qxl.id);
     id = ext.info->id;
     qemu_spice_destroy_update(ssd, (void*)id);
 }
--
1.7.1
SOURCES/kvm-spice-make-sure-we-don-t-overflow-ssd-buf.patch
New file
@@ -0,0 +1,90 @@
From 997ea047468b04f18925ba1309068d69c16bdcc4 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 15 Sep 2014 13:08:23 +0200
Subject: [PATCH 6/6] spice: make sure we don't overflow ssd->buf
Message-id: <1410786503-19794-5-git-send-email-kraxel@redhat.com>
Patchwork-id: 61136
O-Subject: [RHEL-7.1 qemu-kvm PATCH 4/4] spice: make sure we don't overflow ssd->buf
Bugzilla: 1139117
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
Related spice-only bug.  We have a fixed 16 MB buffer here, being
presented to the spice-server as qxl video memory in case spice is
used with a non-qxl card.  It's also used with qxl in vga mode.
When using display resolutions requiring more than 16 MB of memory we
are going to overflow that buffer.  In theory the guest can write,
indirectly via spice-server.  The spice-server clears the memory after
setting a new video mode though, triggering a segfault in the overflow
case, so qemu crashes before the guest has a chance to do something
evil.
Fix that by switching to dynamic allocation for the buffer.
CVE-2014-3615
Cc: qemu-stable@nongnu.org
Cc: secalert@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit ab9509cceabef28071e41bdfa073083859c949a7)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 ui/spice-display.c |   20 +++++++++++++++-----
 1 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index da45282..dce9c1b 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -308,11 +308,23 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
 void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
 {
     QXLDevSurfaceCreate surface;
+    uint64_t surface_size;
     memset(&surface, 0, sizeof(surface));
-    dprint(1, "%s/%d: %dx%d\n", __func__, ssd->qxl.id,
-           surface_width(ssd->ds), surface_height(ssd->ds));
+    surface_size = (uint64_t) surface_width(ssd->ds) *
+        surface_height(ssd->ds) * 4;
+    assert(surface_size > 0);
+    assert(surface_size < INT_MAX);
+    if (ssd->bufsize < surface_size) {
+        ssd->bufsize = surface_size;
+        g_free(ssd->buf);
+        ssd->buf = g_malloc(ssd->bufsize);
+    }
+
+    dprint(1, "%s/%d: %ux%u (size %" PRIu64 "/%d)\n", __func__, ssd->qxl.id,
+           surface_width(ssd->ds), surface_height(ssd->ds),
+           surface_size, ssd->bufsize);
     surface.format     = SPICE_SURFACE_FMT_32_xRGB;
     surface.width      = surface_width(ssd->ds);
@@ -343,8 +355,6 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd)
     if (ssd->num_surfaces == 0) {
         ssd->num_surfaces = 1024;
     }
-    ssd->bufsize = (16 * 1024 * 1024);
-    ssd->buf = g_malloc(ssd->bufsize);
 }
 /* display listener callbacks */
@@ -463,7 +473,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
     info->num_memslots = NUM_MEMSLOTS;
     info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
     info->internal_groupslot_id = 0;
-    info->qxl_ram_size = ssd->bufsize;
+    info->qxl_ram_size = 16 * 1024 * 1024;
     info->n_surfaces = ssd->num_surfaces;
 }
--
1.7.1
SOURCES/kvm-vbe-make-bochs-dispi-interface-return-the-correct-me.patch
New file
@@ -0,0 +1,92 @@
From 110fded1f5457f5c089f865636119140b2ee1f94 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 15 Sep 2014 13:08:20 +0200
Subject: [PATCH 3/6] vbe: make bochs dispi interface return the correct memory size with qxl
Message-id: <1410786503-19794-2-git-send-email-kraxel@redhat.com>
Patchwork-id: 61135
O-Subject: [RHEL-7.1 qemu-kvm PATCH 1/4] vbe: make bochs dispi interface return the correct memory size with qxl
Bugzilla: 1139117
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
VgaState->vram_size is the size of the pci bar.  In case of qxl not the
whole pci bar can be used as vga framebuffer.  Add a new variable
vbe_size to handle that case.  By default (if unset) it equals
vram_size, but qxl can set vbe_size to something else.
This makes sure VBE_DISPI_INDEX_VIDEO_MEMORY_64K returns correct results
and sanity checks are done with the correct size too.
Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit 54a85d462447c1cb8a1638578a7fd086350b4d2d)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/display/qxl.c     |    1 +
 hw/display/vga.c     |    7 +++++--
 hw/display/vga_int.h |    1 +
 3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 4fe4f1b..0ecd64e 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -2046,6 +2046,7 @@ static int qxl_init_primary(PCIDevice *dev)
     qxl->id = 0;
     qxl_init_ramsize(qxl);
+    vga->vbe_size = qxl->vgamem_size;
     vga->vram_size_mb = qxl->vga.vram_size >> 20;
     vga_common_init(vga);
     vga_init(vga, pci_address_space(dev), pci_address_space_io(dev), false);
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 21a108d..d703d90 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -613,7 +613,7 @@ uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
             val = s->vbe_regs[s->vbe_index];
         }
     } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
-        val = s->vram_size / (64 * 1024);
+        val = s->vbe_size / (64 * 1024);
     } else {
         val = 0;
     }
@@ -752,7 +752,7 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
                     line_offset = w >> 1;
                 else
                     line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
-                h = s->vram_size / line_offset;
+                h = s->vbe_size / line_offset;
                 /* XXX: support weird bochs semantics ? */
                 if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
                     return;
@@ -2290,6 +2290,9 @@ void vga_common_init(VGACommonState *s)
         s->vram_size <<= 1;
     }
     s->vram_size_mb = s->vram_size >> 20;
+    if (!s->vbe_size) {
+        s->vbe_size = s->vram_size;
+    }
     s->is_vbe_vmstate = 1;
     memory_region_init_ram(&s->vram, "vga.vram", s->vram_size);
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index 66f9f3c..5a2f466 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -93,6 +93,7 @@ typedef struct VGACommonState {
     MemoryRegion vram_vbe;
     uint32_t vram_size;
     uint32_t vram_size_mb; /* property */
+    uint32_t vbe_size;
     uint32_t latch;
     MemoryRegion *chain4_alias;
     uint8_t sr_index;
--
1.7.1
SOURCES/kvm-vbe-rework-sanity-checks.patch
New file
@@ -0,0 +1,247 @@
From df5995a56f706268a23451204eadb1823a1f93b5 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 15 Sep 2014 13:08:21 +0200
Subject: [PATCH 4/6] vbe: rework sanity checks
Message-id: <1410786503-19794-3-git-send-email-kraxel@redhat.com>
Patchwork-id: 61137
O-Subject: [RHEL-7.1 qemu-kvm PATCH 2/4] vbe: rework sanity checks
Bugzilla: 1139117
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
Plug a bunch of holes in the bochs dispi interface parameter checking.
Add a function doing verification on all registers.  Call that
unconditionally on every register write.  That way we should catch
everything, even changing one register affecting the valid range of
another register.
Some of the holes have been added by commit
e9c6149f6ae6873f14a12eea554925b6aa4c4dec.  Before that commit the
maximum possible framebuffer (VBE_DISPI_MAX_XRES * VBE_DISPI_MAX_YRES *
32 bpp) has been smaller than the qemu vga memory (8MB) and the checking
for VBE_DISPI_MAX_XRES + VBE_DISPI_MAX_YRES + VBE_DISPI_MAX_BPP was ok.
Some of the holes have been there forever, such as
VBE_DISPI_INDEX_X_OFFSET and VBE_DISPI_INDEX_Y_OFFSET register writes
lacking any verification.
Security impact:
(1) Guest can make the ui (gtk/vnc/...) use memory rages outside the vga
frame buffer as source  ->  host memory leak.  Memory isn't leaked to
the guest but to the vnc client though.
(2) Qemu will segfault in case the memory range happens to include
unmapped areas  ->  Guest can DoS itself.
The guest can not modify host memory, so I don't think this can be used
by the guest to escape.
CVE-2014-3615
Cc: qemu-stable@nongnu.org
Cc: secalert@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit c1b886c45dc70f247300f549dce9833f3fa2def5)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/display/vga.c |  154 +++++++++++++++++++++++++++++++++---------------------
 1 files changed, 95 insertions(+), 59 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index d703d90..de5d63d 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -579,6 +579,93 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
+/*
+ * Sanity check vbe register writes.
+ *
+ * As we don't have a way to signal errors to the guest in the bochs
+ * dispi interface we'll go adjust the registers to the closest valid
+ * value.
+ */
+static void vbe_fixup_regs(VGACommonState *s)
+{
+    uint16_t *r = s->vbe_regs;
+    uint32_t bits, linelength, maxy, offset;
+
+    if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
+        /* vbe is turned off -- nothing to do */
+        return;
+    }
+
+    /* check depth */
+    switch (r[VBE_DISPI_INDEX_BPP]) {
+    case 4:
+    case 8:
+    case 16:
+    case 24:
+    case 32:
+        bits = r[VBE_DISPI_INDEX_BPP];
+        break;
+    case 15:
+        bits = 16;
+        break;
+    default:
+        bits = r[VBE_DISPI_INDEX_BPP] = 8;
+        break;
+    }
+
+    /* check width */
+    r[VBE_DISPI_INDEX_XRES] &= ~7u;
+    if (r[VBE_DISPI_INDEX_XRES] == 0) {
+        r[VBE_DISPI_INDEX_XRES] = 8;
+    }
+    if (r[VBE_DISPI_INDEX_XRES] > VBE_DISPI_MAX_XRES) {
+        r[VBE_DISPI_INDEX_XRES] = VBE_DISPI_MAX_XRES;
+    }
+    r[VBE_DISPI_INDEX_VIRT_WIDTH] &= ~7u;
+    if (r[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) {
+        r[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES;
+    }
+    if (r[VBE_DISPI_INDEX_VIRT_WIDTH] < r[VBE_DISPI_INDEX_XRES]) {
+        r[VBE_DISPI_INDEX_VIRT_WIDTH] = r[VBE_DISPI_INDEX_XRES];
+    }
+
+    /* check height */
+    linelength = r[VBE_DISPI_INDEX_VIRT_WIDTH] * bits / 8;
+    maxy = s->vbe_size / linelength;
+    if (r[VBE_DISPI_INDEX_YRES] == 0) {
+        r[VBE_DISPI_INDEX_YRES] = 1;
+    }
+    if (r[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) {
+        r[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES;
+    }
+    if (r[VBE_DISPI_INDEX_YRES] > maxy) {
+        r[VBE_DISPI_INDEX_YRES] = maxy;
+    }
+
+    /* check offset */
+    if (r[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) {
+        r[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES;
+    }
+    if (r[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) {
+        r[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES;
+    }
+    offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
+    offset += r[VBE_DISPI_INDEX_Y_OFFSET] * linelength;
+    if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
+        r[VBE_DISPI_INDEX_Y_OFFSET] = 0;
+        offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
+        if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
+            r[VBE_DISPI_INDEX_X_OFFSET] = 0;
+            offset = 0;
+        }
+    }
+
+    /* update vga state */
+    r[VBE_DISPI_INDEX_VIRT_HEIGHT] = maxy;
+    s->vbe_line_offset = linelength;
+    s->vbe_start_addr  = offset / 4;
+}
+
 static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
 {
     VGACommonState *s = opaque;
@@ -648,22 +735,13 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
             }
             break;
         case VBE_DISPI_INDEX_XRES:
-            if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
-                s->vbe_regs[s->vbe_index] = val;
-            }
-            break;
         case VBE_DISPI_INDEX_YRES:
-            if (val <= VBE_DISPI_MAX_YRES) {
-                s->vbe_regs[s->vbe_index] = val;
-            }
-            break;
         case VBE_DISPI_INDEX_BPP:
-            if (val == 0)
-                val = 8;
-            if (val == 4 || val == 8 || val == 15 ||
-                val == 16 || val == 24 || val == 32) {
-                s->vbe_regs[s->vbe_index] = val;
-            }
+        case VBE_DISPI_INDEX_VIRT_WIDTH:
+        case VBE_DISPI_INDEX_X_OFFSET:
+        case VBE_DISPI_INDEX_Y_OFFSET:
+            s->vbe_regs[s->vbe_index] = val;
+            vbe_fixup_regs(s);
             break;
         case VBE_DISPI_INDEX_BANK:
             if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
@@ -680,19 +758,11 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
                 !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
                 int h, shift_control;
-                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
-                    s->vbe_regs[VBE_DISPI_INDEX_XRES];
-                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
-                    s->vbe_regs[VBE_DISPI_INDEX_YRES];
+                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
-
-                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
-                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
-                else
-                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
-                        ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
-                s->vbe_start_addr = 0;
+                s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
+                vbe_fixup_regs(s);
                 /* clear the screen (should be done in BIOS) */
                 if (!(val & VBE_DISPI_NOCLEARMEM)) {
@@ -741,40 +811,6 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
             s->vbe_regs[s->vbe_index] = val;
             vga_update_memory_access(s);
             break;
-        case VBE_DISPI_INDEX_VIRT_WIDTH:
-            {
-                int w, h, line_offset;
-
-                if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
-                    return;
-                w = val;
-                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
-                    line_offset = w >> 1;
-                else
-                    line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
-                h = s->vbe_size / line_offset;
-                /* XXX: support weird bochs semantics ? */
-                if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
-                    return;
-                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
-                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
-                s->vbe_line_offset = line_offset;
-            }
-            break;
-        case VBE_DISPI_INDEX_X_OFFSET:
-        case VBE_DISPI_INDEX_Y_OFFSET:
-            {
-                int x;
-                s->vbe_regs[s->vbe_index] = val;
-                s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
-                x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
-                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
-                    s->vbe_start_addr += x >> 1;
-                else
-                    s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
-                s->vbe_start_addr >>= 2;
-            }
-            break;
         default:
             break;
         }
--
1.7.1
SOURCES/kvm-vmstate_xhci_event-bug-compat-with-RHEL-7.0-RHEL-onl.patch
New file
@@ -0,0 +1,144 @@
From a0a7c88ceec2443192ec27242b176b66f82dd74a Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Mon, 1 Sep 2014 13:36:53 +0200
Subject: [PATCH 2/6] vmstate_xhci_event: bug compat with RHEL-7.0 (RHEL only)
Message-id: <1409578613-11909-3-git-send-email-lersek@redhat.com>
Patchwork-id: 60782
O-Subject: [PATCH RHEL-7.0.z/RHEL-7.1.0 qemu-kvm 2/2] vmstate_xhci_event: bug compat with RHEL-7.0 (RHEL only)
Bugzilla: 1145055
RH-Acked-by: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
The "vmstate_xhci_event.fields" member is a pointer to an array of
VMStateField elements. The unnamed array (of static storage duration)
comes from a compound literal. The previous patch fixed the undefined
behavior by adding a terminator element to this array, but in RHEL-7 we
also need to look into the practical details of that undefined behavior.
In debug builds (./configure --enable-debug), the compiler places the
"vmstate_xhci_intr.fields" member's unnamed initializer array right after
the "vmstate_xhci_event.fields" member's. This leads to infinite recursion
(see the previous patch for details), but in RHEL-7 we don't ship debug
builds.
In a normal (optimized, official) build, the layout changes. The
"vmstate_xhci_event.fields" member's unterminated initializer array is
followed by the one of the "vmstate_xhci_slot.fields" member:
  (gdb) print (intptr_t)&vmstate_xhci_event.fields[7] - \
              (intptr_t)&vmstate_xhci_slot.fields[0]
  $3 = 0
where "vmstate_xhci_slot.fields" is initialized from
    .fields = (VMStateField[]) {
        VMSTATE_BOOL(enabled,   XHCISlot),
        VMSTATE_BOOL(addressed, XHCISlot),
        VMSTATE_END_OF_LIST()
    }
The elements of this array are (only relevant members quoted):
  (gdb) print vmstate_xhci_slot.fields[0].offset
  $16 = 0
  (gdb) print vmstate_xhci_slot.fields[0].size
  $17 = 1
  (gdb) print vmstate_xhci_slot.fields[1].offset
  $18 = 1
  (gdb) print vmstate_xhci_slot.fields[1].size
  $19 = 1
This means that the wire format for "vmstate_xhci_event" will include the
byte at offset 0 and the byte at offset 1 from XHCIEvent, corresponding to
part of the "XHCIEvent.type" member:
  (gdb) print vmstate_xhci_event.fields[0].name
  $23 = 0x5555558b12e7 "type"
  (gdb) print vmstate_xhci_event.fields[0].offset
  $24 = 0
  (gdb) print vmstate_xhci_event.fields[0].size
  $25 = 4
In order to accommodate these bogus bytes, coming from an unpatched source
side, we introduce two dummy XHCIEvent fields; otherwise the patched
destination would reject the migration stream.
For the reverse direction, we explicitly set the dummy bytes to the values
that they used to take in an unpatched source, so that when the unpatched
destination deserializes them into part of "XHCIEvent.type", said victim
member still receives a correct value.
The dummy fields have type uint8_t, not bool. The reason is that
assignment to bool (in xhci_event_pre_save()) would entail conversion to
bool, hence result in values 0 or 1. (See _Bool conversion rules and
<stdbool.h>.)
RHEL-only because we control the compiler version and the build flags only
in RHEL.
This is for CVE-2014-5263.
Suggested-by: Amit Shah <amit.shah@redhat.com>
Suggested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/usb/hcd-xhci.c |   27 ++++++++++++++++++++-------
 1 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index dbdf6b1..9f97167 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -420,6 +420,8 @@ typedef struct XHCIEvent {
     uint32_t flags;
     uint8_t slotid;
     uint8_t epid;
+    uint8_t cve_2014_5263_a;
+    uint8_t cve_2014_5263_b;
 } XHCIEvent;
 typedef struct XHCIInterrupter {
@@ -3515,17 +3517,28 @@ static const VMStateDescription vmstate_xhci_slot = {
     }
 };
+static void xhci_event_pre_save(void *opaque)
+{
+    XHCIEvent *s = opaque;
+
+    s->cve_2014_5263_a = ((uint8_t *)&s->type)[0];
+    s->cve_2014_5263_b = ((uint8_t *)&s->type)[1];
+}
+
 static const VMStateDescription vmstate_xhci_event = {
     .name = "xhci-event",
     .version_id = 1,
+    .pre_save = xhci_event_pre_save,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32(type,   XHCIEvent),
-        VMSTATE_UINT32(ccode,  XHCIEvent),
-        VMSTATE_UINT64(ptr,    XHCIEvent),
-        VMSTATE_UINT32(length, XHCIEvent),
-        VMSTATE_UINT32(flags,  XHCIEvent),
-        VMSTATE_UINT8(slotid,  XHCIEvent),
-        VMSTATE_UINT8(epid,    XHCIEvent),
+        VMSTATE_UINT32(type,           XHCIEvent),
+        VMSTATE_UINT32(ccode,          XHCIEvent),
+        VMSTATE_UINT64(ptr,            XHCIEvent),
+        VMSTATE_UINT32(length,         XHCIEvent),
+        VMSTATE_UINT32(flags,          XHCIEvent),
+        VMSTATE_UINT8(slotid,          XHCIEvent),
+        VMSTATE_UINT8(epid,            XHCIEvent),
+        VMSTATE_UINT8(cve_2014_5263_a, XHCIEvent),
+        VMSTATE_UINT8(cve_2014_5263_b, XHCIEvent),
         VMSTATE_END_OF_LIST()
     }
 };
--
1.7.1
SOURCES/kvm-vmstate_xhci_event-fix-unterminated-field-list.patch
New file
@@ -0,0 +1,64 @@
From 41d2d56a0fda46b582eab0845f064ba85c9c2456 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Mon, 1 Sep 2014 13:36:52 +0200
Subject: [PATCH 1/6] vmstate_xhci_event: fix unterminated field list
Message-id: <1409578613-11909-2-git-send-email-lersek@redhat.com>
Patchwork-id: 60781
O-Subject: [PATCH RHEL-7.0.z/RHEL-7.1.0 qemu-kvm 1/2] vmstate_xhci_event: fix unterminated field list
Bugzilla: 1145055
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
"vmstate_xhci_event" was introduced in commit 37352df3 ("xhci: add live
migration support"), and first released in v1.6.0. The field list in this
VMSD is not terminated with the VMSTATE_END_OF_LIST() macro.
During normal use (ie. migration), the issue is practically invisible,
because the "vmstate_xhci_event" object (with the unterminated field list)
is only ever referenced -- via "vmstate_xhci_intr" -- if xhci_er_full()
returns true, for the "ev_buffer" test. Since that field_exists() check
(apparently) almost always returns false, we almost never traverse
"vmstate_xhci_event" during migration, which hides the bug.
However, Amit's vmstate checker forces recursion into this VMSD as well,
and the lack of VMSTATE_END_OF_LIST() breaks the field list terminator
check (field->name != NULL) in dump_vmstate_vmsd(). The result is
undefined behavior, which in my case translates to infinite recursion
(because the loop happens to overflow into "vmstate_xhci_intr", which then
links back to "vmstate_xhci_event").
Add the missing terminator.
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 3afca1d6d413592c2b78cf28f52fa24a586d8f56)
RHEL-7 note: this is for CVE-2014-5263.
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/usb/hcd-xhci.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 87ba7af..dbdf6b1 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3526,6 +3526,7 @@ static const VMStateDescription vmstate_xhci_event = {
         VMSTATE_UINT32(flags,  XHCIEvent),
         VMSTATE_UINT8(slotid,  XHCIEvent),
         VMSTATE_UINT8(epid,    XHCIEvent),
+        VMSTATE_END_OF_LIST()
     }
 };
--
1.7.1
SPECS/qemu-kvm.spec
@@ -73,7 +73,7 @@
Summary: QEMU is a FAST! processor emulator
Name: %{pkgname}%{?pkgsuffix}
Version: 1.5.3
Release: 60%{?dist}.7.0.1
Release: 60%{?dist}.10
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 10
License: GPLv2+ and LGPLv2+ and BSD
@@ -2334,6 +2334,28 @@
Patch1140: kvm-qemu-iotests-Test-0-length-image-for-mirror.patch
# For bz#1132806 - advertise active commit to libvirt
Patch1141: kvm-mirror-Fix-qiov-size-for-short-requests.patch
# For bz#1145055 - vmstate_xhci_event: fix unterminated field list [rhel-7.0.z]
Patch1142: kvm-vmstate_xhci_event-fix-unterminated-field-list.patch
# For bz#1145055 - vmstate_xhci_event: fix unterminated field list [rhel-7.0.z]
Patch1143: kvm-vmstate_xhci_event-bug-compat-with-RHEL-7.0-RHEL-onl.patch
# For bz#1139117 - CVE-2014-3615 qemu-kvm: Qemu: crash when guest sets high resolution [rhel-7.0.z]
Patch1144: kvm-vbe-make-bochs-dispi-interface-return-the-correct-me.patch
# For bz#1139117 - CVE-2014-3615 qemu-kvm: Qemu: crash when guest sets high resolution [rhel-7.0.z]
Patch1145: kvm-vbe-rework-sanity-checks.patch
# For bz#1139117 - CVE-2014-3615 qemu-kvm: Qemu: crash when guest sets high resolution [rhel-7.0.z]
Patch1146: kvm-spice-display-add-display-channel-id-to-the-debug-me.patch
# For bz#1139117 - CVE-2014-3615 qemu-kvm: Qemu: crash when guest sets high resolution [rhel-7.0.z]
Patch1147: kvm-spice-make-sure-we-don-t-overflow-ssd-buf.patch
# For bz#1141189 - bug in scsi_block_new_request() function introduced by upstream commit 137745c5c60f083ec982fe9e861e8c16ebca1ba8
Patch1148: kvm-scsi-disk-fix-bug-in-scsi_block_new_request-introduc.patch
# For bz#1122925 - Maintain relative path to backing file image during live merge (block-commit)
Patch1149: kvm-block-add-helper-function-to-determine-if-a-BDS-is-i.patch
# For bz#1122925 - Maintain relative path to backing file image during live merge (block-commit)
Patch1150: kvm-block-extend-block-commit-to-accept-a-string-for-the.patch
# For bz#1122925 - Maintain relative path to backing file image during live merge (block-commit)
Patch1151: kvm-block-add-backing-file-option-to-block-stream.patch
# For bz#1122925 - Maintain relative path to backing file image during live merge (block-commit)
Patch1152: kvm-block-add-__com.redhat_change-backing-file-qmp-comma.patch
BuildRequires: zlib-devel
@@ -3677,6 +3699,17 @@
%patch1139 -p1
%patch1140 -p1
%patch1141 -p1
%patch1142 -p1
%patch1143 -p1
%patch1144 -p1
%patch1145 -p1
%patch1146 -p1
%patch1147 -p1
%patch1148 -p1
%patch1149 -p1
%patch1150 -p1
%patch1151 -p1
%patch1152 -p1
%build
buildarch="%{kvm_target}-softmmu"
@@ -4093,8 +4126,30 @@
%{_libdir}/pkgconfig/libcacard.pc
%changelog
* Mon Sep  8 2014 Johnny Hughes <johnny@centos.org> - 1.5.3-60.el7_0.7.0.1
- Rebuild with a newer kernel, no code changes
* Mon Sep 29 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-60.el7_0.10
- kvm-block-add-helper-function-to-determine-if-a-BDS-is-i.patch [bz#1122925]
- kvm-block-extend-block-commit-to-accept-a-string-for-the.patch [bz#1122925]
- kvm-block-add-backing-file-option-to-block-stream.patch [bz#1122925]
- kvm-block-add-__com.redhat_change-backing-file-qmp-comma.patch [bz#1122925]
- Resolves: bz#1122925
  (Maintain relative path to backing file image during live merge (block-commit))
* Tue Sep 23 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-60.el7_0.9
- kvm-scsi-disk-fix-bug-in-scsi_block_new_request-introduc.patch [bz#1141189]
- Resolves: bz#1141189
  (bug in scsi_block_new_request() function introduced by upstream commit 137745c5c60f083ec982fe9e861e8c16ebca1ba8)
* Mon Sep 22 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-60.el7_0.8
- kvm-vmstate_xhci_event-fix-unterminated-field-list.patch [bz#1145055]
- kvm-vmstate_xhci_event-bug-compat-with-RHEL-7.0-RHEL-onl.patch [bz#1145055]
- kvm-vbe-make-bochs-dispi-interface-return-the-correct-me.patch [bz#1139117]
- kvm-vbe-rework-sanity-checks.patch [bz#1139117]
- kvm-spice-display-add-display-channel-id-to-the-debug-me.patch [bz#1139117]
- kvm-spice-make-sure-we-don-t-overflow-ssd-buf.patch [bz#1139117]
- Resolves: bz#1139117
  (CVE-2014-3615 qemu-kvm: Qemu: crash when guest sets high resolution [rhel-7.0.z])
- Resolves: bz#1145055
  (vmstate_xhci_event: fix unterminated field list [rhel-7.0.z])
* Tue Aug 26 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-60.el7_0.7
- kvm-mirror-Fix-resource-leak-when-bdrv_getlength-fails.patch [bz#1132806]