QEMU is a FAST! processor emulator
CentOS Sources
2014-09-08 2382db1479af0ec735e42a0d4f31c88b95a4fd43
import qemu-kvm-1.5.3-60.el7_0.7
17 files added
1 files modified
1949 ■■■■■ changed files
SOURCES/kvm-block-make-top-argument-to-block-commit-optional.patch 201 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-blockjob-Add-block_job_yield.patch 77 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-memory-Don-t-call-memory_region_update_coalesced_ran.patch 63 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-mirror-Fix-qiov-size-for-short-requests.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-mirror-Fix-resource-leak-when-bdrv_getlength-fails.patch 46 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-mirror-Go-through-ready-complete-process-for-0-len-i.patch 69 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qemu-iotests-Test-0-length-image-for-mirror.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-qemu-iotests-Test-BLOCK_JOB_READY-event-for-0Kb-imag.patch 107 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-Don-t-cache-MSIMessage.patch 80 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-Fix-MSI-X-vector-expansion.patch 95 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-correct-debug-macro-typo.patch 43 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Add-debug-config-options-to-disable-MSI-X-K.patch 82 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Fix-MSI-X-debug-code.patch 42 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vfio-pci-Fix-MSI-X-masking-performance.patch 411 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-net-Do-not-filter-VLANs-without-F_CTRL_VLAN.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-net-add-vlan-receive-state-to-RxFilterInfo.patch 148 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vmstate-reduce-code-duplication.patch 158 ●●●●● patch | view | raw | blame | history
SPECS/qemu-kvm.spec 90 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-make-top-argument-to-block-commit-optional.patch
New file
@@ -0,0 +1,201 @@
From 915f7feb718ab551f6a0c0e05939e369c3aab759 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 20 Aug 2014 16:40:12 +0200
Subject: [PATCH 5/7] block: make 'top' argument to block-commit optional
Message-id: <1408552814-23031-6-git-send-email-eblake@redhat.com>
Patchwork-id: 60647
O-Subject: [qemu-kvm-rhev 7.0.z PATCH 5/7] block: make 'top' argument to block-commit optional
Bugzilla: 1132806
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Jeff Cody <jcody@redhat.com>
Now that active layer block-commit is supported, the 'top' argument
no longer needs to be mandatory.
Change it to optional, with the default being the active layer in the
device chain.
[kwolf: Rebased and resolved conflict in tests/qemu-iotests/040]
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 7676e2c597000eff3a7233b40cca768b358f9bc9)
Conflicts:
    qapi/block-core.json - downstream in qapi-schema.json still
    tests/qemu-iotests/040 - context due to no common event handling
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 blockdev.c             |   16 ++++++++++++++--
 qapi-schema.json       |    7 ++++---
 qmp-commands.hx        |    5 +++--
 tests/qemu-iotests/040 |   28 ++++++++++++++++++----------
 4 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index e51203c..a94c9d3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1463,7 +1463,8 @@ void qmp_block_stream(const char *device, bool has_base,
 }
 void qmp_block_commit(const char *device,
-                      bool has_base, const char *base, const char *top,
+                      bool has_base, const char *base,
+                      bool has_top, const char *top,
                       bool has_speed, int64_t speed,
                       Error **errp)
 {
@@ -1478,6 +1479,11 @@ void qmp_block_commit(const char *device,
     /* drain all i/o before commits */
     bdrv_drain_all();
+    /* Important Note:
+     *  libvirt relies on the DeviceNotFound error class in order to probe for
+     *  live commit feature versions; for this to work, we must make sure to
+     *  perform the device lookup before any generic errors that may occur in a
+     *  scenario in which all optional arguments are omitted. */
     bs = bdrv_find(device);
     if (!bs) {
         error_set(errp, QERR_DEVICE_NOT_FOUND, device);
@@ -1487,7 +1493,7 @@ void qmp_block_commit(const char *device,
     /* default top_bs is the active layer */
     top_bs = bs;
-    if (top) {
+    if (has_top && top) {
         if (strcmp(bs->filename, top) != 0) {
             top_bs = bdrv_find_backing_image(bs, top);
         }
@@ -1509,6 +1515,12 @@ void qmp_block_commit(const char *device,
         return;
     }
+    /* Do not allow attempts to commit an image into itself */
+    if (top_bs == base_bs) {
+        error_setg(errp, "cannot commit an image into itself");
+        return;
+    }
+
     if (top_bs == bs) {
         commit_active_start(bs, base_bs, speed, on_error, block_job_cb,
                             bs, &local_err);
diff --git a/qapi-schema.json b/qapi-schema.json
index aaa86f5..3768872 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1838,8 +1838,9 @@
 # @base:   #optional The file name of the backing image to write data into.
 #                    If not specified, this is the deepest backing image
 #
-# @top:              The file name of the backing image within the image chain,
-#                    which contains the topmost data to be committed down.
+# @top:    #optional The file name of the backing image within the image chain,
+#                    which contains the topmost data to be committed down. If
+#                    not specified, this is the active layer.
 #
 #                    If top == base, that is an error.
 #                    If top == active, the job will not be completed by itself,
@@ -1867,7 +1868,7 @@
 #
 ##
 { 'command': 'block-commit',
-  'data': { 'device': 'str', '*base': 'str', 'top': 'str',
+  'data': { 'device': 'str', '*base': 'str', '*top': 'str',
             '*speed': 'int' } }
 ##
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 1d4be84..b6b6246 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?,speed:o?",
         .mhandler.cmd_new = qmp_marshal_input_block_commit,
     },
@@ -1023,7 +1023,8 @@ Arguments:
           If not specified, this is the deepest backing image
           (json-string, optional)
 - "top":  The file name of the backing image within the image chain,
-          which contains the topmost data to be committed down.
+          which contains the topmost data to be committed down. If
+          not specified, this is the active layer. (json-string, optional)
           If top == base, that is an error.
           If top == active, the job will not be completed by itself,
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index cf80e0c..c5ab930 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -63,11 +63,7 @@ class ImageCommitTestCase(iotests.QMPTestCase):
             i = i + 512
         file.close()
-    def run_commit_test(self, top, base, need_ready=False):
-        self.assert_no_active_commit()
-        result = self.vm.qmp('block-commit', device='drive0', top=top, base=base)
-        self.assert_qmp(result, 'return', {})
-
+    def wait_for_complete(self, need_ready=False):
         completed = False
         ready = False
         while not completed:
@@ -90,6 +86,18 @@ class ImageCommitTestCase(iotests.QMPTestCase):
         self.assert_no_active_commit()
         self.vm.shutdown()
+    def run_commit_test(self, top, base, need_ready=False):
+        self.assert_no_active_commit()
+        result = self.vm.qmp('block-commit', device='drive0', top=top, base=base)
+        self.assert_qmp(result, 'return', {})
+        self.wait_for_complete(need_ready)
+
+    def run_default_commit_test(self):
+        self.assert_no_active_commit()
+        result = self.vm.qmp('block-commit', device='drive0')
+        self.assert_qmp(result, 'return', {})
+        self.wait_for_complete()
+
 class TestSingleDrive(ImageCommitTestCase):
     image_len = 1 * 1024 * 1024
     test_len = 1 * 1024 * 256
@@ -141,17 +149,17 @@ class TestSingleDrive(ImageCommitTestCase):
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+    def test_top_is_default_active(self):
+        self.run_default_commit_test()
+        self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+
     def test_top_and_base_reversed(self):
         self.assert_no_active_commit()
         result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % mid_img)
         self.assert_qmp(result, 'error/class', 'GenericError')
         self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mid_img)
-    def test_top_omitted(self):
-        self.assert_no_active_commit()
-        result = self.vm.qmp('block-commit', device='drive0')
-        self.assert_qmp(result, 'error/class', 'GenericError')
-        self.assert_qmp(result, 'error/desc', "Parameter 'top' is missing")
 class TestRelativePaths(ImageCommitTestCase):
     image_len = 1 * 1024 * 1024
--
1.7.1
SOURCES/kvm-blockjob-Add-block_job_yield.patch
New file
@@ -0,0 +1,77 @@
From c1c69c1b13d64f7d892c8b661714fe388b1a6047 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 20 Aug 2014 16:40:09 +0200
Subject: [PATCH 2/7] blockjob: Add block_job_yield()
Message-id: <1408552814-23031-3-git-send-email-eblake@redhat.com>
Patchwork-id: 60644
O-Subject: [qemu-kvm-rhev 7.0.z PATCH 2/7] blockjob: Add block_job_yield()
Bugzilla: 1132806
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Fam Zheng <famz@redhat.com>
This will unset busy flag and put coroutine to sleep, can be used to
wait for QMP complete/cancel.
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit dc71ce45ded4e872e25c2de32d5e7a71842b0985)
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 blockjob.c               |   14 ++++++++++++++
 include/block/blockjob.h |    8 ++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/blockjob.c b/blockjob.c
index a4430a0..1117ee7 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -206,6 +206,20 @@ void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns)
     job->busy = true;
 }
+void block_job_yield(BlockJob *job)
+{
+    assert(job->busy);
+
+    /* Check cancellation *before* setting busy = false, too!  */
+    if (block_job_is_cancelled(job)) {
+        return;
+    }
+
+    job->busy = false;
+    qemu_coroutine_yield();
+    job->busy = true;
+}
+
 BlockJobInfo *block_job_query(BlockJob *job)
 {
     BlockJobInfo *info = g_new0(BlockJobInfo, 1);
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 5a7d859..11f7c7e 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -144,6 +144,14 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
 void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns);
 /**
+ * block_job_yield:
+ * @job: The job that calls the function.
+ *
+ * Yield the block job coroutine.
+ */
+void block_job_yield(BlockJob *job);
+
+/**
  * block_job_completed:
  * @job: The job being completed.
  * @ret: The status code.
--
1.7.1
SOURCES/kvm-memory-Don-t-call-memory_region_update_coalesced_ran.patch
New file
@@ -0,0 +1,63 @@
From 6e840c55cf077c166740a837edd92b8346be2cb9 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famz@redhat.com>
Date: Fri, 8 Aug 2014 03:23:27 +0200
Subject: [PATCH 10/10] memory: Don't call memory_region_update_coalesced_range if nothing changed
Message-id: <1407468207-28928-1-git-send-email-famz@redhat.com>
Patchwork-id: 60486
O-Subject: [RHEL-7.0.z qemu-kvm PATCH] memory: Don't call memory_region_update_coalesced_range if nothing changed
Bugzilla: 1124660
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1124660
Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7805797
With huge number of PCI devices in the system (for example, 200
virtio-blk-pci), this unconditional call can slow down emulation of
irrelevant PCI operations drastically, such as a BAR update on a device
that has no coalescing region. So avoid it.
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit ab5b3db5d711b290d63e954dc64647dd51cef962)
Signed-off-by: Fam Zheng <famz@redhat.com>
---
 memory.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 memory.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/memory.c b/memory.c
index edaf6fd..a71d096 100644
--- a/memory.c
+++ b/memory.c
@@ -1210,6 +1210,7 @@ void memory_region_add_coalescing(MemoryRegion *mr,
 void memory_region_clear_coalescing(MemoryRegion *mr)
 {
     CoalescedMemoryRange *cmr;
+    bool updated = false;
     qemu_flush_coalesced_mmio_buffer();
     mr->flush_coalesced_mmio = false;
@@ -1218,8 +1219,12 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
         cmr = QTAILQ_FIRST(&mr->coalesced);
         QTAILQ_REMOVE(&mr->coalesced, cmr, link);
         g_free(cmr);
+        updated = true;
+    }
+
+    if (updated) {
+        memory_region_update_coalesced_range(mr);
     }
-    memory_region_update_coalesced_range(mr);
 }
 void memory_region_set_flush_coalesced(MemoryRegion *mr)
--
1.7.1
SOURCES/kvm-mirror-Fix-qiov-size-for-short-requests.patch
New file
@@ -0,0 +1,93 @@
From cb60b78e889e738f88e4c056d7312290869e4f1d Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 20 Aug 2014 16:40:14 +0200
Subject: [PATCH 7/7] mirror: Fix qiov size for short requests
Message-id: <1408552814-23031-8-git-send-email-eblake@redhat.com>
Patchwork-id: 60650
O-Subject: [qemu-kvm-rhev 7.0.z PATCH 7/7] mirror: Fix qiov size for short requests
Bugzilla: 1132806
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Kevin Wolf <kwolf@redhat.com>
When mirroring an image of a size that is not a multiple of the
mirror job granularity, the last request would have the right nb_sectors
argument, but a qiov that is rounded up to the next multiple of the
granularity. Don't do this.
This fixes a segfault that is caused by raw-posix being confused by this
and allocating a buffer with request length, but operating on it with
qiov length.
[s/Driver/Drive/ in qemu-iotests 041 as suggested by Eric
--Stefan]
Reported-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 5a0f6fd5c84573387056e0464a7fc0c6fb70b2dc)
Conflicts:
    tests/qemu-iotests/041.out - context with fewer tests run downstream
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/mirror.c             |    4 +++-
 tests/qemu-iotests/041     |    5 +++++
 tests/qemu-iotests/041.out |    4 ++--
 3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index cdc0268..b7cf4ab 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -243,9 +243,11 @@ static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
     next_sector = sector_num;
     while (nb_chunks-- > 0) {
         MirrorBuffer *buf = QSIMPLEQ_FIRST(&s->buf_free);
+        size_t remaining = (nb_sectors * BDRV_SECTOR_SIZE) - op->qiov.size;
+
         QSIMPLEQ_REMOVE_HEAD(&s->buf_free, next);
         s->buf_free_count--;
-        qemu_iovec_add(&op->qiov, buf, s->granularity);
+        qemu_iovec_add(&op->qiov, buf, MIN(s->granularity, remaining));
         /* Advance the HBitmapIter in parallel, so that we do not examine
          * the same sector twice.
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index 912e499..b654081 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -270,6 +270,11 @@ class TestSingleDriveZeroLength(TestSingleDrive):
     test_small_buffer2 = None
     test_large_cluster = None
+class TestSingleDriveUnalignedLength(TestSingleDrive):
+    image_len = 1025 * 1024
+    test_small_buffer2 = None
+    test_large_cluster = None
+
 class TestMirrorNoBacking(ImageMirroringTestCase):
     image_len = 2 * 1024 * 1024 # MB
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
index cfa5c0d..802ffaa 100644
--- a/tests/qemu-iotests/041.out
+++ b/tests/qemu-iotests/041.out
@@ -1,5 +1,5 @@
-...................................
+...........................................
 ----------------------------------------------------------------------
-Ran 35 tests
+Ran 43 tests
 OK
--
1.7.1
SOURCES/kvm-mirror-Fix-resource-leak-when-bdrv_getlength-fails.patch
New file
@@ -0,0 +1,46 @@
From 64f938d5b7ae0c2b1029b9816f45c8e5c0e0f560 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 20 Aug 2014 16:40:08 +0200
Subject: [PATCH 1/7] mirror: Fix resource leak when bdrv_getlength fails
Message-id: <1408552814-23031-2-git-send-email-eblake@redhat.com>
Patchwork-id: 60646
O-Subject: [qemu-kvm-rhev 7.0.z PATCH 1/7] mirror: Fix resource leak when bdrv_getlength fails
Bugzilla: 1132806
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Fam Zheng <famz@redhat.com>
The direct return will skip releasing of all the resouces at
immediate_exit, don't miss that.
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 373df5b135b4a54e0abb394e9e703fef3ded093c)
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/mirror.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 47e14cd..9b3e229 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -307,8 +307,8 @@ static void coroutine_fn mirror_run(void *opaque)
     s->common.len = bdrv_getlength(bs);
     if (s->common.len <= 0) {
-        block_job_completed(&s->common, s->common.len);
-        return;
+        ret = s->common.len;
+        goto immediate_exit;
     }
     length = (bdrv_getlength(bs) + s->granularity - 1) / s->granularity;
--
1.7.1
SOURCES/kvm-mirror-Go-through-ready-complete-process-for-0-len-i.patch
New file
@@ -0,0 +1,69 @@
From a437bfcdaad8e387709506ccaa992895f76afa8e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 20 Aug 2014 16:40:10 +0200
Subject: [PATCH 3/7] mirror: Go through ready -> complete process for 0 len image
Message-id: <1408552814-23031-4-git-send-email-eblake@redhat.com>
Patchwork-id: 60645
O-Subject: [qemu-kvm-rhev 7.0.z PATCH 3/7] mirror: Go through ready -> complete process for 0 len image
Bugzilla: 1132806
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Fam Zheng <famz@redhat.com>
When mirroring or active committing a zero length image, BLOCK_JOB_READY
is not reported now, instead the job completes because we short circuit
the mirror job loop.
This is inconsistent with non-zero length images, and only confuses
management software.
Let's do the same thing when seeing a 0-length image: report ready
immediately; wait for block-job-cancel or block-job-complete; clear the
cancel flag as existing non-zero image synced case (cancelled after
ready); then jump to the exit.
Reported-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9e48b025400b2d284e17860862b0a4aa02c6032d)
Conflicts:
    block/mirror.c - no backport of qapi events
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/mirror.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 9b3e229..cdc0268 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -306,9 +306,18 @@ static void coroutine_fn mirror_run(void *opaque)
     }
     s->common.len = bdrv_getlength(bs);
-    if (s->common.len <= 0) {
+    if (s->common.len < 0) {
         ret = s->common.len;
         goto immediate_exit;
+    } else if (s->common.len == 0) {
+        /* Report BLOCK_JOB_READY and wait for complete. */
+        block_job_ready(&s->common);
+        s->synced = true;
+        while (!block_job_is_cancelled(&s->common) && !s->should_complete) {
+            block_job_yield(&s->common);
+        }
+        s->common.cancelled = false;
+        goto immediate_exit;
     }
     length = (bdrv_getlength(bs) + s->granularity - 1) / s->granularity;
--
1.7.1
SOURCES/kvm-qemu-iotests-Test-0-length-image-for-mirror.patch
New file
@@ -0,0 +1,93 @@
From 8042a9daf7913e39b7ee4f6417f1d934e5dabbff Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 20 Aug 2014 16:40:13 +0200
Subject: [PATCH 6/7] qemu-iotests: Test 0-length image for mirror
Message-id: <1408552814-23031-7-git-send-email-eblake@redhat.com>
Patchwork-id: 60648
O-Subject: [qemu-kvm-rhev 7.0.z PATCH 6/7] qemu-iotests: Test 0-length image for mirror
Bugzilla: 1132806
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Fam Zheng <famz@redhat.com>
All behavior and invariant should hold for images with 0 length, so
add a class to repeat all the tests in TestSingleDrive.
Hide two unapplicable test methods that would fail with 0 image length
because it's also used as cluster size.
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 3b9f27d2b34cb8c5cc6cec993712c7e1943e9de9)
Conflicts:
    tests/qemu-iotests/041 - context due to no common event handling
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 tests/qemu-iotests/041     |   11 ++++++++---
 tests/qemu-iotests/041.out |    4 ++--
 2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index bcfb759..912e499 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -123,7 +123,7 @@ class TestSingleDrive(ImageMirroringTestCase):
     image_len = 1 * 1024 * 1024 # MB
     def setUp(self):
-        self.create_image(backing_img, TestSingleDrive.image_len)
+        self.create_image(backing_img, self.image_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
         self.vm = iotests.VM().add_drive(test_img)
         self.vm.launch()
@@ -222,7 +222,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         self.assert_no_active_block_jobs()
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,size=%d'
-                        % (TestSingleDrive.image_len, TestSingleDrive.image_len), target_img)
+                        % (self.image_len, self.image_len), target_img)
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              buf_size=65536, mode='existing', target=target_img)
         self.assert_qmp(result, 'return', {})
@@ -238,7 +238,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         self.assert_no_active_block_jobs()
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
-                        % (TestSingleDrive.image_len, backing_img), target_img)
+                        % (self.image_len, backing_img), target_img)
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              mode='existing', target=target_img)
         self.assert_qmp(result, 'return', {})
@@ -265,6 +265,11 @@ class TestSingleDrive(ImageMirroringTestCase):
                              target=target_img)
         self.assert_qmp(result, 'error/class', 'DeviceNotFound')
+class TestSingleDriveZeroLength(TestSingleDrive):
+    image_len = 0
+    test_small_buffer2 = None
+    test_large_cluster = None
+
 class TestMirrorNoBacking(ImageMirroringTestCase):
     image_len = 2 * 1024 * 1024 # MB
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
index 6d9bee1..cfa5c0d 100644
--- a/tests/qemu-iotests/041.out
+++ b/tests/qemu-iotests/041.out
@@ -1,5 +1,5 @@
-...........................
+...................................
 ----------------------------------------------------------------------
-Ran 27 tests
+Ran 35 tests
 OK
--
1.7.1
SOURCES/kvm-qemu-iotests-Test-BLOCK_JOB_READY-event-for-0Kb-imag.patch
New file
@@ -0,0 +1,107 @@
From 2b17bf64d8b033b7a85b67597282d1751d027d7a Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 20 Aug 2014 16:40:11 +0200
Subject: [PATCH 4/7] qemu-iotests: Test BLOCK_JOB_READY event for 0Kb image active commit
Message-id: <1408552814-23031-5-git-send-email-eblake@redhat.com>
Patchwork-id: 60649
O-Subject: [qemu-kvm-rhev 7.0.z PATCH 4/7] qemu-iotests: Test BLOCK_JOB_READY event for 0Kb image active commit
Bugzilla: 1132806
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Fam Zheng <famz@redhat.com>
There should be a BLOCK_JOB_READY event with active commit, regardless
of image length. Let's test the 0 length image case, and make sure it
goes through the ready->complete process.
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8b9a30ca5bc10545637429486836f3c206c39fab)
Conflicts:
    tests/qemu-iotests/040 - context, due to no common event infrastructure
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 tests/qemu-iotests/040     |   12 +++++++++---
 tests/qemu-iotests/040.out |    4 ++--
 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index f210fb7..cf80e0c 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -63,12 +63,13 @@ class ImageCommitTestCase(iotests.QMPTestCase):
             i = i + 512
         file.close()
-    def run_commit_test(self, top, base):
+    def run_commit_test(self, top, base, need_ready=False):
         self.assert_no_active_commit()
         result = self.vm.qmp('block-commit', device='drive0', top=top, base=base)
         self.assert_qmp(result, 'return', {})
         completed = False
+        ready = False
         while not completed:
             for event in self.vm.get_qmp_events(wait=True):
                 if event['event'] == 'BLOCK_JOB_COMPLETED':
@@ -76,8 +77,11 @@ class ImageCommitTestCase(iotests.QMPTestCase):
                     self.assert_qmp(event, 'data/device', 'drive0')
                     self.assert_qmp(event, 'data/offset', self.image_len)
                     self.assert_qmp(event, 'data/len', self.image_len)
+                    if need_ready:
+                        self.assertTrue(ready, "Expecting BLOCK_JOB_COMPLETED event")
                     completed = True
                 elif event['event'] == 'BLOCK_JOB_READY':
+                    ready = True
                     self.assert_qmp(event, 'data/type', 'commit')
                     self.assert_qmp(event, 'data/device', 'drive0')
                     self.assert_qmp(event, 'data/len', self.image_len)
@@ -91,7 +95,7 @@ class TestSingleDrive(ImageCommitTestCase):
     test_len = 1 * 1024 * 256
     def setUp(self):
-        self.create_image(backing_img, TestSingleDrive.image_len)
+        self.create_image(backing_img, self.image_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
         qemu_io('-c', 'write -P 0xab 0 524288', backing_img)
@@ -133,7 +137,7 @@ class TestSingleDrive(ImageCommitTestCase):
         self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')
     def test_top_is_active(self):
-        self.run_commit_test(test_img, backing_img)
+        self.run_commit_test(test_img, backing_img, need_ready=True)
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
         self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
@@ -265,6 +269,8 @@ class TestSetSpeed(ImageCommitTestCase):
         self.cancel_and_wait()
+class TestActiveZeroLengthImage(TestSingleDrive):
+    image_len = 0
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2', 'qed'])
diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out
index b6f2576..42314e9 100644
--- a/tests/qemu-iotests/040.out
+++ b/tests/qemu-iotests/040.out
@@ -1,5 +1,5 @@
-................
+........................
 ----------------------------------------------------------------------
-Ran 16 tests
+Ran 24 tests
 OK
--
1.7.1
SOURCES/kvm-vfio-Don-t-cache-MSIMessage.patch
New file
@@ -0,0 +1,80 @@
From f0550083eabcc0fff10cd8a55ed534f8563ce022 Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Thu, 7 Aug 2014 21:03:20 +0200
Subject: [PATCH 07/10] vfio: Don't cache MSIMessage
Message-id: <20140807210320.11689.35203.stgit@gimli.home>
Patchwork-id: 60483
O-Subject: [RHEL7.0/z qemu-kvm PATCH v2 6/6] vfio: Don't cache MSIMessage
Bugzilla: 1110693 1110695
RH-Acked-by: Bandan Das <bsd@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
Upstream: 9b3af4c0e40f14b5173ad6e2d9fcc376207ec1dd
Commit 40509f7f added a test to avoid updating KVM MSI routes when the
MSIMessage is unchanged and f4d45d47 switched to relying on this
rather than doing our own comparison.  Our cached msg is effectively
unused now.  Remove it.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/misc/vfio.c |    8 ++------
 1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 688e2ef..abaa4c1 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -131,7 +131,6 @@ typedef struct VFIOMSIVector {
     EventNotifier interrupt;
     EventNotifier kvm_interrupt;
     struct VFIODevice *vdev; /* back pointer to device */
-    MSIMessage msg; /* cache the MSI message so we know when it changes */
     int virq;
     bool use;
 } VFIOMSIVector;
@@ -725,7 +724,6 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,
         return;
     }
-    vector->msg = *msg;
     vector->virq = virq;
 }
@@ -741,7 +739,6 @@ static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
 static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg)
 {
     kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
-    vector->msg = msg;
 }
 static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
@@ -920,6 +917,7 @@ retry:
     for (i = 0; i < vdev->nr_vectors; i++) {
         VFIOMSIVector *vector = &vdev->msi_vectors[i];
+        MSIMessage msg = msi_get_message(&vdev->pdev, i);
         vector->vdev = vdev;
         vector->virq = -1;
@@ -932,13 +930,11 @@ retry:
         qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
                             vfio_msi_interrupt, NULL, vector);
-        vector->msg = msi_get_message(&vdev->pdev, i);
-
         /*
          * Attempt to enable route through KVM irqchip,
          * default to userspace handling if unavailable.
          */
-        vfio_add_kvm_msi_virq(vector, &vector->msg, false);
+        vfio_add_kvm_msi_virq(vector, &msg, false);
     }
     /* Set interrupt type prior to possible interrupts */
--
1.7.1
SOURCES/kvm-vfio-Fix-MSI-X-vector-expansion.patch
New file
@@ -0,0 +1,95 @@
From bdd720aafc6099e126b682f70e4163e1b2097594 Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Thu, 7 Aug 2014 21:03:14 +0200
Subject: [PATCH 06/10] vfio: Fix MSI-X vector expansion
Message-id: <20140807210314.11689.89693.stgit@gimli.home>
Patchwork-id: 60482
O-Subject: [RHEL7.0/z qemu-kvm PATCH v2 5/6] vfio: Fix MSI-X vector expansion
Bugzilla: 1110693 1110695
RH-Acked-by: Bandan Das <bsd@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
Upstream: c048be5cc92ae201c339d46984476c4629275ed6
When new MSI-X vectors are enabled we need to disable MSI-X and
re-enable it with the correct number of vectors.  That means we need
to reprogram the eventfd triggers for each vector.  Prior to f4d45d47
vector->use tracked whether a vector was masked or unmasked and we
could always pick the KVM path when available for unmasked vectors.
Now vfio doesn't track mask state itself and vector->use and virq
remains configured even for masked vectors.  Therefore we need to ask
the MSI-X code whether a vector is masked in order to select the
correct signaling path.  As noted in the comment, MSI relies on
hardware to handle masking.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-stable@nongnu.org # QEMU 2.1
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/misc/vfio.c |   38 +++++++++++++++++++++++++++++---------
 1 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index bd37924..688e2ef 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -119,11 +119,20 @@ typedef struct VFIOINTx {
 } VFIOINTx;
 typedef struct VFIOMSIVector {
-    EventNotifier interrupt; /* eventfd triggered on interrupt */
-    EventNotifier kvm_interrupt; /* eventfd triggered for KVM irqfd bypass */
+    /*
+     * Two interrupt paths are configured per vector.  The first, is only used
+     * for interrupts injected via QEMU.  This is typically the non-accel path,
+     * but may also be used when we want QEMU to handle masking and pending
+     * bits.  The KVM path bypasses QEMU and is therefore higher performance,
+     * but requires masking at the device.  virq is used to track the MSI route
+     * through KVM, thus kvm_interrupt is only available when virq is set to a
+     * valid (>= 0) value.
+     */
+    EventNotifier interrupt;
+    EventNotifier kvm_interrupt;
     struct VFIODevice *vdev; /* back pointer to device */
     MSIMessage msg; /* cache the MSI message so we know when it changes */
-    int virq; /* KVM irqchip route for QEMU bypass */
+    int virq;
     bool use;
 } VFIOMSIVector;
@@ -662,13 +671,24 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
     fds = (int32_t *)&irq_set->data;
     for (i = 0; i < vdev->nr_vectors; i++) {
-        if (!vdev->msi_vectors[i].use) {
-            fds[i] = -1;
-        } else if (vdev->msi_vectors[i].virq >= 0) {
-            fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
-        } else {
-            fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
+        int fd = -1;
+
+        /*
+         * MSI vs MSI-X - The guest has direct access to MSI mask and pending
+         * bits, therefore we always use the KVM signaling path when setup.
+         * MSI-X mask and pending bits are emulated, so we want to use the
+         * KVM signaling path only when configured and unmasked.
+         */
+        if (vdev->msi_vectors[i].use) {
+            if (vdev->msi_vectors[i].virq < 0 ||
+                (msix && msix_is_masked(&vdev->pdev, i))) {
+                fd = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
+            } else {
+                fd = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
+            }
         }
+
+        fds[i] = fd;
     }
     ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
--
1.7.1
SOURCES/kvm-vfio-correct-debug-macro-typo.patch
New file
@@ -0,0 +1,43 @@
From 18f67233db4f428332e100ccb194090675db0cdb Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Thu, 7 Aug 2014 21:02:57 +0200
Subject: [PATCH 03/10] vfio: correct debug macro typo
Message-id: <20140807210257.11689.30368.stgit@gimli.home>
Patchwork-id: 60479
O-Subject: [RHEL7.0/z qemu-kvm PATCH v2 2/6] vfio: correct debug macro typo
Bugzilla: 1110693 1110695
RH-Acked-by: Bandan Das <bsd@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
From: Bandan Das <bsd@redhat.com>
Upstream: 8b6d14087d487203f4d1a67aeaddc3be6c73f49f
Change to DEBUG_VFIO in vfio_msi_interrupt() for debug
messages to get printed
Signed-off-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/misc/vfio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index b5387ca..7f6ebf9 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -619,7 +619,7 @@ static void vfio_msi_interrupt(void *opaque)
         return;
     }
-#ifdef VFIO_DEBUG
+#ifdef DEBUG_VFIO
     MSIMessage msg;
     if (vdev->interrupt == VFIO_INT_MSIX) {
--
1.7.1
SOURCES/kvm-vfio-pci-Add-debug-config-options-to-disable-MSI-X-K.patch
New file
@@ -0,0 +1,82 @@
From 8b417dd4a269341d4167ac7df64285869d37af58 Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Thu, 7 Aug 2014 21:02:51 +0200
Subject: [PATCH 02/10] vfio-pci: Add debug config options to disable MSI/X KVM support
Message-id: <20140807210251.11689.35960.stgit@gimli.home>
Patchwork-id: 60478
O-Subject: [RHEL7.0/z qemu-kvm PATCH v2 1/6] vfio-pci: Add debug config options to disable MSI/X KVM support
Bugzilla: 1110693 1110695
RH-Acked-by: Bandan Das <bsd@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
It's sometimes useful to be able to verify interrupts are passing
through correctly.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/misc/vfio.c |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index b04170e..b5387ca 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -52,6 +52,8 @@
 /* Extra debugging, trap acceleration paths for more logging */
 #define VFIO_ALLOW_MMAP 1
 #define VFIO_ALLOW_KVM_INTX 1
+#define VFIO_ALLOW_KVM_MSI 1
+#define VFIO_ALLOW_KVM_MSIX 1
 struct VFIODevice;
@@ -617,9 +619,21 @@ static void vfio_msi_interrupt(void *opaque)
         return;
     }
-    DPRINTF("%s(%04x:%02x:%02x.%x) vector %d\n", __func__,
+#ifdef VFIO_DEBUG
+    MSIMessage msg;
+
+    if (vdev->interrupt == VFIO_INT_MSIX) {
+        msg = msi_get_message(&vdev->pdev, nr);
+    } else if (vdev->interrupt == VFIO_INT_MSI) {
+        msg = msix_get_message(&vdev->pdev, nr);
+    } else {
+        abort();
+    }
+
+    DPRINTF("%s(%04x:%02x:%02x.%x) vector %d 0x%"PRIx64"/0x%x\n", __func__,
             vdev->host.domain, vdev->host.bus, vdev->host.slot,
-            vdev->host.function, nr);
+            vdev->host.function, nr, msg.address, msg.data);
+#endif
     if (vdev->interrupt == VFIO_INT_MSIX) {
         msix_notify(&vdev->pdev, nr);
@@ -687,7 +701,8 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
      * Attempt to enable route through KVM irqchip,
      * default to userspace handling if unavailable.
      */
-    vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
+    vector->virq = msg && VFIO_ALLOW_KVM_MSIX ?
+                   kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
     if (vector->virq < 0 ||
         kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
                                        vector->virq) < 0) {
@@ -854,7 +869,8 @@ retry:
          * Attempt to enable route through KVM irqchip,
          * default to userspace handling if unavailable.
          */
-        vector->virq = kvm_irqchip_add_msi_route(kvm_state, vector->msg);
+        vector->virq = VFIO_ALLOW_KVM_MSI ?
+                       kvm_irqchip_add_msi_route(kvm_state, vector->msg) : -1;
         if (vector->virq < 0 ||
             kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
                                            vector->virq) < 0) {
--
1.7.1
SOURCES/kvm-vfio-pci-Fix-MSI-X-debug-code.patch
New file
@@ -0,0 +1,42 @@
From 1311f877741665964f5c6a56854a033ad704ef46 Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Thu, 7 Aug 2014 21:03:03 +0200
Subject: [PATCH 04/10] vfio-pci: Fix MSI/X debug code
Message-id: <20140807210302.11689.73901.stgit@gimli.home>
Patchwork-id: 60480
O-Subject: [RHEL7.0/z qemu-kvm PATCH v2 3/6] vfio-pci: Fix MSI/X debug code
Bugzilla: 1110693 1110695
RH-Acked-by: Bandan Das <bsd@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
Upstream: 9035f8c09bebb63c0cc6014acf5c7066ef778aff
Use the correct MSI message function for debug info.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/misc/vfio.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 7f6ebf9..5f0460a 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -623,9 +623,9 @@ static void vfio_msi_interrupt(void *opaque)
     MSIMessage msg;
     if (vdev->interrupt == VFIO_INT_MSIX) {
-        msg = msi_get_message(&vdev->pdev, nr);
-    } else if (vdev->interrupt == VFIO_INT_MSI) {
         msg = msix_get_message(&vdev->pdev, nr);
+    } else if (vdev->interrupt == VFIO_INT_MSI) {
+        msg = msi_get_message(&vdev->pdev, nr);
     } else {
         abort();
     }
--
1.7.1
SOURCES/kvm-vfio-pci-Fix-MSI-X-masking-performance.patch
New file
@@ -0,0 +1,411 @@
From a48a4761390e9aa917ebef7628dfc72f905910ee Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Thu, 7 Aug 2014 21:03:08 +0200
Subject: [PATCH 05/10] vfio-pci: Fix MSI-X masking performance
Message-id: <20140807210308.11689.93757.stgit@gimli.home>
Patchwork-id: 60481
O-Subject: [RHEL7.0/z qemu-kvm PATCH v2 4/6] vfio-pci: Fix MSI-X masking performance
Bugzilla: 1110693 1110695
RH-Acked-by: Bandan Das <bsd@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
Upstream: f4d45d47826377722700894dbf7f47444527a9d2
There are still old guests out there that over-exercise MSI-X masking.
The current code completely sets-up and tears-down an MSI-X vector on
the "use" and "release" callbacks.  While this is functional, it can
slow an old guest to a crawl.  We can easily skip the KVM parts of
this so that we keep the MSI route and irqfd setup.  We do however
need to switch VFIO to trigger a different eventfd while masked.
Actually, we have the option of continuing to use -1 to disable the
trigger, but by using another EventNotifier we can allow the MSI-X
core to emulate pending bits and re-fire the vector once unmasked.
MSI code gets updated as well to use the same setup and teardown
structures and functions.
Prior to this change, an igbvf assigned to a RHEL5 guest gets about
20Mbps and 50 transactions/s with netperf (remote or VF->PF).  With
this change, we get line rate and 3k transactions/s remote or 2Gbps
and 6k+ transactions/s to the PF.  No significant change is expected
for newer guests with more well behaved MSI-X support.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/misc/vfio.c |  233 +++++++++++++++++++++++++++++++------------------------
 1 files changed, 131 insertions(+), 102 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 5f0460a..bd37924 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -120,6 +120,7 @@ typedef struct VFIOINTx {
 typedef struct VFIOMSIVector {
     EventNotifier interrupt; /* eventfd triggered on interrupt */
+    EventNotifier kvm_interrupt; /* eventfd triggered for KVM irqfd bypass */
     struct VFIODevice *vdev; /* back pointer to device */
     MSIMessage msg; /* cache the MSI message so we know when it changes */
     int virq; /* KVM irqchip route for QEMU bypass */
@@ -663,10 +664,11 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
     for (i = 0; i < vdev->nr_vectors; i++) {
         if (!vdev->msi_vectors[i].use) {
             fds[i] = -1;
-            continue;
+        } else if (vdev->msi_vectors[i].virq >= 0) {
+            fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
+        } else {
+            fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
         }
-
-        fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
     }
     ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
@@ -676,6 +678,52 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
     return ret;
 }
+static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,
+                                  bool msix)
+{
+    int virq;
+
+    if ((msix && !VFIO_ALLOW_KVM_MSIX) ||
+        (!msix && !VFIO_ALLOW_KVM_MSI) || !msg) {
+        return;
+    }
+
+    if (event_notifier_init(&vector->kvm_interrupt, 0)) {
+        return;
+    }
+
+    virq = kvm_irqchip_add_msi_route(kvm_state, *msg);
+    if (virq < 0) {
+        event_notifier_cleanup(&vector->kvm_interrupt);
+        return;
+    }
+
+    if (kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->kvm_interrupt,
+                                       virq) < 0) {
+        kvm_irqchip_release_virq(kvm_state, virq);
+        event_notifier_cleanup(&vector->kvm_interrupt);
+        return;
+    }
+
+    vector->msg = *msg;
+    vector->virq = virq;
+}
+
+static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
+{
+    kvm_irqchip_remove_irqfd_notifier(kvm_state, &vector->kvm_interrupt,
+                                      vector->virq);
+    kvm_irqchip_release_virq(kvm_state, vector->virq);
+    vector->virq = -1;
+    event_notifier_cleanup(&vector->kvm_interrupt);
+}
+
+static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg)
+{
+    kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
+    vector->msg = msg;
+}
+
 static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
                                    MSIMessage *msg, IOHandler *handler)
 {
@@ -688,30 +736,32 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
             vdev->host.function, nr);
     vector = &vdev->msi_vectors[nr];
-    vector->vdev = vdev;
-    vector->use = true;
-
-    msix_vector_use(pdev, nr);
-    if (event_notifier_init(&vector->interrupt, 0)) {
-        error_report("vfio: Error: event_notifier_init failed");
+    if (!vector->use) {
+        vector->vdev = vdev;
+        vector->virq = -1;
+        if (event_notifier_init(&vector->interrupt, 0)) {
+            error_report("vfio: Error: event_notifier_init failed");
+        }
+        vector->use = true;
+        msix_vector_use(pdev, nr);
     }
+    qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
+                        handler, NULL, vector);
+
     /*
      * Attempt to enable route through KVM irqchip,
      * default to userspace handling if unavailable.
      */
-    vector->virq = msg && VFIO_ALLOW_KVM_MSIX ?
-                   kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
-    if (vector->virq < 0 ||
-        kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
-                                       vector->virq) < 0) {
-        if (vector->virq >= 0) {
-            kvm_irqchip_release_virq(kvm_state, vector->virq);
-            vector->virq = -1;
+    if (vector->virq >= 0) {
+        if (!msg) {
+            vfio_remove_kvm_msi_virq(vector);
+        } else {
+            vfio_update_kvm_msi_virq(vector, *msg);
         }
-        qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
-                            handler, NULL, vector);
+    } else {
+        vfio_add_kvm_msi_virq(vector, msg, true);
     }
     /*
@@ -742,7 +792,11 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
         irq_set->count = 1;
         pfd = (int32_t *)&irq_set->data;
-        *pfd = event_notifier_get_fd(&vector->interrupt);
+        if (vector->virq >= 0) {
+            *pfd = event_notifier_get_fd(&vector->kvm_interrupt);
+        } else {
+            *pfd = event_notifier_get_fd(&vector->interrupt);
+        }
         ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
         g_free(irq_set);
@@ -764,50 +818,41 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
 {
     VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
     VFIOMSIVector *vector = &vdev->msi_vectors[nr];
-    int argsz;
-    struct vfio_irq_set *irq_set;
-    int32_t *pfd;
     DPRINTF("%s(%04x:%02x:%02x.%x) vector %d released\n", __func__,
             vdev->host.domain, vdev->host.bus, vdev->host.slot,
             vdev->host.function, nr);
     /*
-     * XXX What's the right thing to do here?  This turns off the interrupt
-     * completely, but do we really just want to switch the interrupt to
-     * bouncing through userspace and let msix.c drop it?  Not sure.
+     * There are still old guests that mask and unmask vectors on every
+     * interrupt.  If we're using QEMU bypass with a KVM irqfd, leave all of
+     * the KVM setup in place, simply switch VFIO to use the non-bypass
+     * eventfd.  We'll then fire the interrupt through QEMU and the MSI-X
+     * core will mask the interrupt and set pending bits, allowing it to
+     * be re-asserted on unmask.  Nothing to do if already using QEMU mode.
      */
-    msix_vector_unuse(pdev, nr);
-
-    argsz = sizeof(*irq_set) + sizeof(*pfd);
+    if (vector->virq >= 0) {
+        int argsz;
+        struct vfio_irq_set *irq_set;
+        int32_t *pfd;
-    irq_set = g_malloc0(argsz);
-    irq_set->argsz = argsz;
-    irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
-                     VFIO_IRQ_SET_ACTION_TRIGGER;
-    irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
-    irq_set->start = nr;
-    irq_set->count = 1;
-    pfd = (int32_t *)&irq_set->data;
+        argsz = sizeof(*irq_set) + sizeof(*pfd);
-    *pfd = -1;
+        irq_set = g_malloc0(argsz);
+        irq_set->argsz = argsz;
+        irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+                         VFIO_IRQ_SET_ACTION_TRIGGER;
+        irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+        irq_set->start = nr;
+        irq_set->count = 1;
+        pfd = (int32_t *)&irq_set->data;
-    ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
+        *pfd = event_notifier_get_fd(&vector->interrupt);
-    g_free(irq_set);
+        ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
-    if (vector->virq < 0) {
-        qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
-                            NULL, NULL, NULL);
-    } else {
-        kvm_irqchip_remove_irqfd_notifier(kvm_state, &vector->interrupt,
-                                          vector->virq);
-        kvm_irqchip_release_virq(kvm_state, vector->virq);
-        vector->virq = -1;
+        g_free(irq_set);
     }
-
-    event_notifier_cleanup(&vector->interrupt);
-    vector->use = false;
 }
 static void vfio_enable_msix(VFIODevice *vdev)
@@ -857,28 +902,28 @@ retry:
         VFIOMSIVector *vector = &vdev->msi_vectors[i];
         vector->vdev = vdev;
+        vector->virq = -1;
         vector->use = true;
         if (event_notifier_init(&vector->interrupt, 0)) {
             error_report("vfio: Error: event_notifier_init failed");
         }
+        qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
+                            vfio_msi_interrupt, NULL, vector);
+
         vector->msg = msi_get_message(&vdev->pdev, i);
         /*
          * Attempt to enable route through KVM irqchip,
          * default to userspace handling if unavailable.
          */
-        vector->virq = VFIO_ALLOW_KVM_MSI ?
-                       kvm_irqchip_add_msi_route(kvm_state, vector->msg) : -1;
-        if (vector->virq < 0 ||
-            kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
-                                           vector->virq) < 0) {
-            qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
-                                vfio_msi_interrupt, NULL, vector);
-        }
+        vfio_add_kvm_msi_virq(vector, &vector->msg, false);
     }
+    /* Set interrupt type prior to possible interrupts */
+    vdev->interrupt = VFIO_INT_MSI;
+
     ret = vfio_enable_vectors(vdev, false);
     if (ret) {
         if (ret < 0) {
@@ -891,14 +936,10 @@ retry:
         for (i = 0; i < vdev->nr_vectors; i++) {
             VFIOMSIVector *vector = &vdev->msi_vectors[i];
             if (vector->virq >= 0) {
-                kvm_irqchip_remove_irqfd_notifier(kvm_state, &vector->interrupt,
-                                                  vector->virq);
-                kvm_irqchip_release_virq(kvm_state, vector->virq);
-                vector->virq = -1;
-            } else {
-                qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
-                                    NULL, NULL, NULL);
+                vfio_remove_kvm_msi_virq(vector);
             }
+            qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
+                                NULL, NULL, NULL);
             event_notifier_cleanup(&vector->interrupt);
         }
@@ -910,11 +951,17 @@ retry:
         }
         vdev->nr_vectors = 0;
+        /*
+         * Failing to setup MSI doesn't really fall within any specification.
+         * Let's try leaving interrupts disabled and hope the guest figures
+         * out to fall back to INTx for this device.
+         */
+        error_report("vfio: Error: Failed to enable MSI");
+        vdev->interrupt = VFIO_INT_NONE;
+
         return;
     }
-    vdev->interrupt = VFIO_INT_MSI;
-
     DPRINTF("%s(%04x:%02x:%02x.%x) Enabled %d MSI vectors\n", __func__,
             vdev->host.domain, vdev->host.bus, vdev->host.slot,
             vdev->host.function, vdev->nr_vectors);
@@ -922,6 +969,20 @@ retry:
 static void vfio_disable_msi_common(VFIODevice *vdev)
 {
+    int i;
+
+    for (i = 0; i < vdev->nr_vectors; i++) {
+        VFIOMSIVector *vector = &vdev->msi_vectors[i];
+        if (vdev->msi_vectors[i].use) {
+            if (vector->virq >= 0) {
+                vfio_remove_kvm_msi_virq(vector);
+            }
+            qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
+                                NULL, NULL, NULL);
+            event_notifier_cleanup(&vector->interrupt);
+        }
+    }
+
     g_free(vdev->msi_vectors);
     vdev->msi_vectors = NULL;
     vdev->nr_vectors = 0;
@@ -943,6 +1004,7 @@ static void vfio_disable_msix(VFIODevice *vdev)
     for (i = 0; i < vdev->nr_vectors; i++) {
         if (vdev->msi_vectors[i].use) {
             vfio_msix_vector_release(&vdev->pdev, i);
+            msix_vector_unuse(&vdev->pdev, i);
         }
     }
@@ -958,30 +1020,7 @@ static void vfio_disable_msix(VFIODevice *vdev)
 static void vfio_disable_msi(VFIODevice *vdev)
 {
-    int i;
-
     vfio_disable_irqindex(vdev, VFIO_PCI_MSI_IRQ_INDEX);
-
-    for (i = 0; i < vdev->nr_vectors; i++) {
-        VFIOMSIVector *vector = &vdev->msi_vectors[i];
-
-        if (!vector->use) {
-            continue;
-        }
-
-        if (vector->virq >= 0) {
-            kvm_irqchip_remove_irqfd_notifier(kvm_state,
-                                              &vector->interrupt, vector->virq);
-            kvm_irqchip_release_virq(kvm_state, vector->virq);
-            vector->virq = -1;
-        } else {
-            qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
-                                NULL, NULL, NULL);
-        }
-
-        event_notifier_cleanup(&vector->interrupt);
-    }
-
     vfio_disable_msi_common(vdev);
     DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
@@ -1001,17 +1040,7 @@ static void vfio_update_msi(VFIODevice *vdev)
         }
         msg = msi_get_message(&vdev->pdev, i);
-
-        if (msg.address != vector->msg.address ||
-            msg.data != vector->msg.data) {
-
-            DPRINTF("%s(%04x:%02x:%02x.%x) MSI vector %d changed\n",
-                    __func__, vdev->host.domain, vdev->host.bus,
-                    vdev->host.slot, vdev->host.function, i);
-
-            kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
-            vector->msg = msg;
-        }
+        vfio_update_kvm_msi_virq(vector, msg);
     }
 }
--
1.7.1
SOURCES/kvm-virtio-net-Do-not-filter-VLANs-without-F_CTRL_VLAN.patch
New file
@@ -0,0 +1,51 @@
From 75ccf361064e8eb2fc7f5e7606cbd0760c9baf7e Mon Sep 17 00:00:00 2001
From: Amos Kong <akong@redhat.com>
Date: Mon, 4 Aug 2014 04:12:07 +0200
Subject: [PATCH 08/10] virtio-net: Do not filter VLANs without F_CTRL_VLAN
Message-id: <1407125528-27862-2-git-send-email-akong@redhat.com>
Patchwork-id: 60415
O-Subject: [RHEL-7.1/7.0.z qemu-kvm PATCH 1/2] virtio-net: Do not filter VLANs without F_CTRL_VLAN
Bugzilla: 1130149
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
RH-Acked-by: Vlad Yasevich <vyasevic@redhat.com>
From: Stefan Fritsch <sf@sfritsch.de>
If VIRTIO_NET_F_CTRL_VLAN is not negotiated, do not filter out all
VLAN-tagged packets but send them to the guest.
This fixes VLANs with OpenBSD guests (and probably NetBSD, too, because
the OpenBSD driver started as a port from NetBSD).
Signed-off-by: Stefan Fritsch <sf@sfritsch.de>
Signed-off-by: Amos Kong <akong@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 0b1eaa8803e680de9a05727355dfe3d306b81e17)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/net/virtio-net.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f72be9f..8e58139 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -490,6 +490,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
         }
         vhost_net_ack_features(tap_get_vhost_net(nc->peer), features);
     }
+
+    if ((1 << VIRTIO_NET_F_CTRL_VLAN) & features) {
+        memset(n->vlans, 0, MAX_VLAN >> 3);
+    } else {
+        memset(n->vlans, 0xff, MAX_VLAN >> 3);
+    }
 }
 static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
--
1.7.1
SOURCES/kvm-virtio-net-add-vlan-receive-state-to-RxFilterInfo.patch
New file
@@ -0,0 +1,148 @@
From 2bfc8b6bf5e03e3b8c0c7dc1743f719cc4273784 Mon Sep 17 00:00:00 2001
From: Amos Kong <akong@redhat.com>
Date: Mon, 4 Aug 2014 04:12:08 +0200
Subject: [PATCH 09/10] virtio-net: add vlan receive state to RxFilterInfo
Message-id: <1407125528-27862-3-git-send-email-akong@redhat.com>
Patchwork-id: 60416
O-Subject: [RHEL-7.1/7.0.z qemu-kvm PATCH 2/2] virtio-net: add vlan receive state to RxFilterInfo
Bugzilla: 1130149
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
RH-Acked-by: Vlad Yasevich <vyasevic@redhat.com>
Stefan Fritsch just fixed a virtio-net driver bug [1], virtio-net won't
filter out VLAN-tagged packets if VIRTIO_NET_F_CTRL_VLAN isn't negotiated.
This patch added a new field to @RxFilterInfo to indicate vlan receive
state ('normal', 'none', 'all'). If VIRTIO_NET_F_CTRL_VLAN isn't
negotiated, vlan receive state will be 'all', then all VLAN-tagged packets
will be received by guest.
This patch also fixed a boundary issue in visiting vlan table.
[1] http://lists.nongnu.org/archive/html/qemu-devel/2014-02/msg02604.html
Signed-off-by: Amos Kong <akong@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(backport from commit f7bc8ef8091229a4bec0e2a40af90abb8dcb3834)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/net/virtio-net.c |   42 +++++++++++++++++++++++++++++-------------
 qapi-schema.json    |    3 +++
 qmp-commands.hx     |    2 ++
 3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 8e58139..4a50869 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -222,13 +222,33 @@ static char *mac_strdup_printf(const uint8_t *mac)
                             mac[1], mac[2], mac[3], mac[4], mac[5]);
 }
+static intList *get_vlan_table(VirtIONet *n)
+{
+    intList *list, *entry;
+    int i, j;
+
+    list = NULL;
+    for (i = 0; i < MAX_VLAN >> 5; i++) {
+        for (j = 0; n->vlans[i] && j <= 0x1f; j++) {
+            if (n->vlans[i] & (1U << j)) {
+                entry = g_malloc0(sizeof(*entry));
+                entry->value = (i << 5) + j;
+                entry->next = list;
+                list = entry;
+            }
+        }
+    }
+
+    return list;
+}
+
 static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
 {
     VirtIONet *n = qemu_get_nic_opaque(nc);
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
     RxFilterInfo *info;
     strList *str_list, *entry;
-    intList *int_list, *int_entry;
-    int i, j;
+    int i;
     info = g_malloc0(sizeof(*info));
     info->name = g_strdup(nc->name);
@@ -273,19 +293,15 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
         str_list = entry;
     }
     info->multicast_table = str_list;
+    info->vlan_table = get_vlan_table(n);
-    int_list = NULL;
-    for (i = 0; i < MAX_VLAN >> 5; i++) {
-        for (j = 0; n->vlans[i] && j < 0x1f; j++) {
-            if (n->vlans[i] & (1U << j)) {
-                int_entry = g_malloc0(sizeof(*int_entry));
-                int_entry->value = (i << 5) + j;
-                int_entry->next = int_list;
-                int_list = int_entry;
-            }
-        }
+    if (!((1 << VIRTIO_NET_F_CTRL_VLAN) & vdev->guest_features)) {
+        info->vlan = RX_STATE_ALL;
+    } else if (!info->vlan_table) {
+        info->vlan = RX_STATE_NONE;
+    } else {
+        info->vlan = RX_STATE_NORMAL;
     }
-    info->vlan_table = int_list;
     /* enable event notification after query */
     nc->rxfilter_notify_enabled = 1;
diff --git a/qapi-schema.json b/qapi-schema.json
index 017b3b7..aaa86f5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4044,6 +4044,8 @@
 #
 # @unicast: unicast receive state
 #
+# @vlan: vlan receive state (Since 2.0)
+#
 # @broadcast-allowed: whether to receive broadcast
 #
 # @multicast-overflow: multicast table is overflowed or not
@@ -4067,6 +4069,7 @@
     'promiscuous':        'bool',
     'multicast':          'RxState',
     'unicast':            'RxState',
+    'vlan':               'RxState',
     'broadcast-allowed':  'bool',
     'multicast-overflow': 'bool',
     'unicast-overflow':   'bool',
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 08a01ee..1d4be84 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3230,6 +3230,7 @@ Each array entry contains the following:
 - "promiscuous": promiscuous mode is enabled (json-bool)
 - "multicast": multicast receive state (one of 'normal', 'none', 'all')
 - "unicast": unicast receive state  (one of 'normal', 'none', 'all')
+- "vlan": vlan receive state (one of 'normal', 'none', 'all') (Since 2.0)
 - "broadcast-allowed": allow to receive broadcast (json-bool)
 - "multicast-overflow": multicast table is overflowed (json-bool)
 - "unicast-overflow": unicast table is overflowed (json-bool)
@@ -3247,6 +3248,7 @@ Example:
             "name": "vnet0",
             "main-mac": "52:54:00:12:34:56",
             "unicast": "normal",
+            "vlan": "normal",
             "vlan-table": [
                 4,
                 0
--
1.7.1
SOURCES/kvm-vmstate-reduce-code-duplication.patch
New file
@@ -0,0 +1,158 @@
From 8f92bf7e5891ec22b84b7969f24e6918ee5a9e38 Mon Sep 17 00:00:00 2001
From: Michael S. Tsirkin <mst@redhat.com>
Date: Wed, 14 May 2014 08:24:25 +0200
Subject: [PATCH 01/10] vmstate: reduce code duplication
Message-id: <1400055633-6261-1-git-send-email-mst@redhat.com>
Patchwork-id: 58848
O-Subject: [PATCH qemu-kvm RHEL7.0.z 1/5] vmstate: reduce code duplication
Bugzilla: 1095706
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Marcel Apfelbaum <marcel.a@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
move size offset and number of elements math out
to functions, to reduce code duplication.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 35fc1f71899fd42323bd8f33da18f0211e0d2727)
---
 savevm.c | 100 +++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 52 insertions(+), 48 deletions(-)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 savevm.c |  100 ++++++++++++++++++++++++++++++++-----------------------------
 1 files changed, 52 insertions(+), 48 deletions(-)
diff --git a/savevm.c b/savevm.c
index 5d1b563..94512dd 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1675,6 +1675,50 @@ static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
                                    void *opaque);
+static int vmstate_n_elems(void *opaque, VMStateField *field)
+{
+    int n_elems = 1;
+
+    if (field->flags & VMS_ARRAY) {
+        n_elems = field->num;
+    } else if (field->flags & VMS_VARRAY_INT32) {
+        n_elems = *(int32_t *)(opaque+field->num_offset);
+    } else if (field->flags & VMS_VARRAY_UINT32) {
+        n_elems = *(uint32_t *)(opaque+field->num_offset);
+    } else if (field->flags & VMS_VARRAY_UINT16) {
+        n_elems = *(uint16_t *)(opaque+field->num_offset);
+    } else if (field->flags & VMS_VARRAY_UINT8) {
+        n_elems = *(uint8_t *)(opaque+field->num_offset);
+    }
+
+    return n_elems;
+}
+
+static int vmstate_size(void *opaque, VMStateField *field)
+{
+    int size = field->size;
+
+    if (field->flags & VMS_VBUFFER) {
+        size = *(int32_t *)(opaque+field->size_offset);
+        if (field->flags & VMS_MULTIPLY) {
+            size *= field->size;
+        }
+    }
+
+    return size;
+}
+
+static void *vmstate_base_addr(void *opaque, VMStateField *field)
+{
+    void *base_addr = opaque + field->offset;
+
+    if (field->flags & VMS_POINTER) {
+        base_addr = *(void **)base_addr + field->start;
+    }
+
+    return base_addr;
+}
+
 int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
                        void *opaque, int version_id)
 {
@@ -1700,30 +1744,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
              field->field_exists(opaque, version_id)) ||
             (!field->field_exists &&
              field->version_id <= version_id)) {
-            void *base_addr = opaque + field->offset;
-            int i, n_elems = 1;
-            int size = field->size;
-
-            if (field->flags & VMS_VBUFFER) {
-                size = *(int32_t *)(opaque+field->size_offset);
-                if (field->flags & VMS_MULTIPLY) {
-                    size *= field->size;
-                }
-            }
-            if (field->flags & VMS_ARRAY) {
-                n_elems = field->num;
-            } else if (field->flags & VMS_VARRAY_INT32) {
-                n_elems = *(int32_t *)(opaque+field->num_offset);
-            } else if (field->flags & VMS_VARRAY_UINT32) {
-                n_elems = *(uint32_t *)(opaque+field->num_offset);
-            } else if (field->flags & VMS_VARRAY_UINT16) {
-                n_elems = *(uint16_t *)(opaque+field->num_offset);
-            } else if (field->flags & VMS_VARRAY_UINT8) {
-                n_elems = *(uint8_t *)(opaque+field->num_offset);
-            }
-            if (field->flags & VMS_POINTER) {
-                base_addr = *(void **)base_addr + field->start;
-            }
+            void *base_addr = vmstate_base_addr(opaque, field);
+            int i, n_elems = vmstate_n_elems(opaque, field);
+            int size = vmstate_size(opaque, field);
+
             for (i = 0; i < n_elems; i++) {
                 void *addr = base_addr + size * i;
@@ -1768,30 +1792,10 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
     while(field->name) {
         if (!field->field_exists ||
             field->field_exists(opaque, vmsd->version_id)) {
-            void *base_addr = opaque + field->offset;
-            int i, n_elems = 1;
-            int size = field->size;
-
-            if (field->flags & VMS_VBUFFER) {
-                size = *(int32_t *)(opaque+field->size_offset);
-                if (field->flags & VMS_MULTIPLY) {
-                    size *= field->size;
-                }
-            }
-            if (field->flags & VMS_ARRAY) {
-                n_elems = field->num;
-            } else if (field->flags & VMS_VARRAY_INT32) {
-                n_elems = *(int32_t *)(opaque+field->num_offset);
-            } else if (field->flags & VMS_VARRAY_UINT32) {
-                n_elems = *(uint32_t *)(opaque+field->num_offset);
-            } else if (field->flags & VMS_VARRAY_UINT16) {
-                n_elems = *(uint16_t *)(opaque+field->num_offset);
-            } else if (field->flags & VMS_VARRAY_UINT8) {
-                n_elems = *(uint8_t *)(opaque+field->num_offset);
-            }
-            if (field->flags & VMS_POINTER) {
-                base_addr = *(void **)base_addr + field->start;
-            }
+            void *base_addr = vmstate_base_addr(opaque, field);
+            int i, n_elems = vmstate_n_elems(opaque, field);
+            int size = vmstate_size(opaque, field);
+
             for (i = 0; i < n_elems; i++) {
                 void *addr = base_addr + size * i;
--
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}.5
Release: 60%{?dist}.7
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 10
License: GPLv2+ and LGPLv2+ and BSD
@@ -2294,6 +2294,46 @@
Patch1123: kvm-skip-system-call-when-msi-route-is-unchanged.patch
# For bz#1095782 - CVE-2014-0182 qemu-kvm: qemu: virtio: out-of-bounds buffer write on state load with invalid config_len [rhel-7.0.z]
Patch1124: kvm-Allow-mismatched-virtio-config-len.patch
# For bz#1095706 - CVE-2013-4527 qemu-kvm: qemu: hpet: buffer overrun on invalid state load [rhel-7.0.z]
Patch1125: kvm-vmstate-reduce-code-duplication.patch
# For bz#1110693 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
# For bz#1110695 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
Patch1126: kvm-vfio-pci-Add-debug-config-options-to-disable-MSI-X-K.patch
# For bz#1110693 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
# For bz#1110695 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
Patch1127: kvm-vfio-correct-debug-macro-typo.patch
# For bz#1110693 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
# For bz#1110695 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
Patch1128: kvm-vfio-pci-Fix-MSI-X-debug-code.patch
# For bz#1110693 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
# For bz#1110695 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
Patch1129: kvm-vfio-pci-Fix-MSI-X-masking-performance.patch
# For bz#1110693 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
# For bz#1110695 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
Patch1130: kvm-vfio-Fix-MSI-X-vector-expansion.patch
# For bz#1110693 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
# For bz#1110695 - 2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput
Patch1131: kvm-vfio-Don-t-cache-MSIMessage.patch
# For bz#1130149 - rx filter incorrect when guest disables VLAN filtering
Patch1132: kvm-virtio-net-Do-not-filter-VLANs-without-F_CTRL_VLAN.patch
# For bz#1130149 - rx filter incorrect when guest disables VLAN filtering
Patch1133: kvm-virtio-net-add-vlan-receive-state-to-RxFilterInfo.patch
# For bz#1124660 - [FJ7.0 Bug] RHEL7.0 guest attaching 150 or more virtio-blk disks fails to start up
Patch1134: kvm-memory-Don-t-call-memory_region_update_coalesced_ran.patch
# For bz#1132806 - advertise active commit to libvirt
Patch1135: kvm-mirror-Fix-resource-leak-when-bdrv_getlength-fails.patch
# For bz#1132806 - advertise active commit to libvirt
Patch1136: kvm-blockjob-Add-block_job_yield.patch
# For bz#1132806 - advertise active commit to libvirt
Patch1137: kvm-mirror-Go-through-ready-complete-process-for-0-len-i.patch
# For bz#1132806 - advertise active commit to libvirt
Patch1138: kvm-qemu-iotests-Test-BLOCK_JOB_READY-event-for-0Kb-imag.patch
# For bz#1132806 - advertise active commit to libvirt
Patch1139: kvm-block-make-top-argument-to-block-commit-optional.patch
# For bz#1132806 - advertise active commit to libvirt
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
BuildRequires: zlib-devel
@@ -3620,6 +3660,23 @@
%patch1122 -p1
%patch1123 -p1
%patch1124 -p1
%patch1125 -p1
%patch1126 -p1
%patch1127 -p1
%patch1128 -p1
%patch1129 -p1
%patch1130 -p1
%patch1131 -p1
%patch1132 -p1
%patch1133 -p1
%patch1134 -p1
%patch1135 -p1
%patch1136 -p1
%patch1137 -p1
%patch1138 -p1
%patch1139 -p1
%patch1140 -p1
%patch1141 -p1
%build
buildarch="%{kvm_target}-softmmu"
@@ -4036,6 +4093,37 @@
%{_libdir}/pkgconfig/libcacard.pc
%changelog
* 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]
- kvm-blockjob-Add-block_job_yield.patch [bz#1132806]
- kvm-mirror-Go-through-ready-complete-process-for-0-len-i.patch [bz#1132806]
- kvm-qemu-iotests-Test-BLOCK_JOB_READY-event-for-0Kb-imag.patch [bz#1132806]
- kvm-block-make-top-argument-to-block-commit-optional.patch [bz#1132806]
- kvm-qemu-iotests-Test-0-length-image-for-mirror.patch [bz#1132806]
- kvm-mirror-Fix-qiov-size-for-short-requests.patch [bz#1132806]
- Resolves: bz#1132806
  (advertise active commit to libvirt)
* Fri Aug 15 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-60.el7_0.6
- kvm-vmstate-reduce-code-duplication.patch [bz#1095706]
- kvm-vfio-pci-Add-debug-config-options-to-disable-MSI-X-K.patch [bz#1110693 bz#1110695]
- kvm-vfio-correct-debug-macro-typo.patch [bz#1110693 bz#1110695]
- kvm-vfio-pci-Fix-MSI-X-debug-code.patch [bz#1110693 bz#1110695]
- kvm-vfio-pci-Fix-MSI-X-masking-performance.patch [bz#1110693 bz#1110695]
- kvm-vfio-Fix-MSI-X-vector-expansion.patch [bz#1110693 bz#1110695]
- kvm-vfio-Don-t-cache-MSIMessage.patch [bz#1110693 bz#1110695]
- kvm-virtio-net-Do-not-filter-VLANs-without-F_CTRL_VLAN.patch [bz#1130149]
- kvm-virtio-net-add-vlan-receive-state-to-RxFilterInfo.patch [bz#1130149]
- kvm-memory-Don-t-call-memory_region_update_coalesced_ran.patch [bz#1124660]
- Resolves: bz#1110693
  (2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput)
- Resolves: bz#1110695
  (2x RHEL 5.10 VM running on RHEL 7 KVM have low TCP_STREAM throughput)
- Resolves: bz#1124660
  ([FJ7.0 Bug] RHEL7.0 guest attaching 150 or more virtio-blk disks fails to start up)
- Resolves: bz#1130149
  (rx filter incorrect when guest disables VLAN filtering)
* Wed Jul 02 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-60.el7_0.5
- kvm-Allow-mismatched-virtio-config-len.patch [bz#1095782]
- Resolves: bz#1095782