[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 09/17] hw/virtio/vhost: re-factor vhost-section and allow DIRTY_ME
From: |
Alex Bennée |
Subject: |
[PULL 09/17] hw/virtio/vhost: re-factor vhost-section and allow DIRTY_MEMORY_CODE |
Date: |
Tue, 9 Jun 2020 11:38:01 +0100 |
The purpose of vhost_section is to identify RAM regions that need to
be made available to a vhost client. However when running under TCG
all RAM sections have DIRTY_MEMORY_CODE set which leads to problems
down the line.
Re-factor the code so:
- steps are clearer to follow
- reason for rejection is recorded in the trace point
- we allow DIRTY_MEMORY_CODE
We expand the comment to explain that kernel based vhost has specific
support for migration tracking.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Fabiano Rosas <farosas@linux.ibm.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20200605154929.26910-11-alex.bennee@linaro.org>
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index aff98a0ede5..e3e21812905 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -27,6 +27,7 @@
#include "migration/blocker.h"
#include "migration/qemu-file-types.h"
#include "sysemu/dma.h"
+#include "sysemu/tcg.h"
#include "trace.h"
/* enabled until disconnected backend stabilizes */
@@ -403,26 +404,50 @@ static int vhost_verify_ring_mappings(struct vhost_dev
*dev,
return r;
}
+/*
+ * vhost_section: identify sections needed for vhost access
+ *
+ * We only care about RAM sections here (where virtqueue and guest
+ * internals accessed by virtio might live). If we find one we still
+ * allow the backend to potentially filter it out of our list.
+ */
static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *section)
{
- bool result;
- bool log_dirty = memory_region_get_dirty_log_mask(section->mr) &
- ~(1 << DIRTY_MEMORY_MIGRATION);
- result = memory_region_is_ram(section->mr) &&
- !memory_region_is_rom(section->mr);
-
- /* Vhost doesn't handle any block which is doing dirty-tracking other
- * than migration; this typically fires on VGA areas.
- */
- result &= !log_dirty;
+ MemoryRegion *mr = section->mr;
+
+ if (memory_region_is_ram(mr) && !memory_region_is_rom(mr)) {
+ uint8_t dirty_mask = memory_region_get_dirty_log_mask(mr);
+ uint8_t handled_dirty;
+
+ /*
+ * Kernel based vhost doesn't handle any block which is doing
+ * dirty-tracking other than migration for which it has
+ * specific logging support. However for TCG the kernel never
+ * gets involved anyway so we can also ignore it's
+ * self-modiying code detection flags. However a vhost-user
+ * client could still confuse a TCG guest if it re-writes
+ * executable memory that has already been translated.
+ */
+ handled_dirty = (1 << DIRTY_MEMORY_MIGRATION) |
+ (1 << DIRTY_MEMORY_CODE);
- if (result && dev->vhost_ops->vhost_backend_mem_section_filter) {
- result &=
- dev->vhost_ops->vhost_backend_mem_section_filter(dev, section);
- }
+ if (dirty_mask & ~handled_dirty) {
+ trace_vhost_reject_section(mr->name, 1);
+ return false;
+ }
+
+ if (dev->vhost_ops->vhost_backend_mem_section_filter &&
+ !dev->vhost_ops->vhost_backend_mem_section_filter(dev, section)) {
+ trace_vhost_reject_section(mr->name, 2);
+ return false;
+ }
- trace_vhost_section(section->mr->name, result);
- return result;
+ trace_vhost_section(mr->name);
+ return true;
+ } else {
+ trace_vhost_reject_section(mr->name, 3);
+ return false;
+ }
}
static void vhost_begin(MemoryListener *listener)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index e83500bee92..6427a0047df 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -5,7 +5,8 @@ vhost_commit(bool started, bool changed) "Started: %d Changed:
%d"
vhost_region_add_section(const char *name, uint64_t gpa, uint64_t size,
uint64_t host) "%s: 0x%"PRIx64"+0x%"PRIx64" @ 0x%"PRIx64
vhost_region_add_section_merge(const char *name, uint64_t new_size, uint64_t
gpa, uint64_t owr) "%s: size: 0x%"PRIx64 " gpa: 0x%"PRIx64 " owr: 0x%"PRIx64
vhost_region_add_section_aligned(const char *name, uint64_t gpa, uint64_t
size, uint64_t host) "%s: 0x%"PRIx64"+0x%"PRIx64" @ 0x%"PRIx64
-vhost_section(const char *name, int r) "%s:%d"
+vhost_section(const char *name) "%s"
+vhost_reject_section(const char *name, int d) "%s:%d"
vhost_iotlb_miss(void *dev, int step) "%p step %d"
# vhost-user.c
--
2.20.1
- [PULL 00/17] testing and misc fixes, Alex Bennée, 2020/06/09
- [PULL 01/17] qemu-plugin.h: add missing include <stddef.h> to define size_t, Alex Bennée, 2020/06/09
- [PULL 04/17] exec: flush the whole TLB if a watchpoint crosses a page boundary, Alex Bennée, 2020/06/09
- [PULL 03/17] tests/plugin: correctly honour io_count, Alex Bennée, 2020/06/09
- [PULL 02/17] scripts/clean-includes: Mark 'qemu/qemu-plugin.h' as special header, Alex Bennée, 2020/06/09
- [PULL 12/17] tests/tcg: add simple commpage test case, Alex Bennée, 2020/06/09
- [PULL 05/17] .travis.yml: allow failure for unreliable hosts, Alex Bennée, 2020/06/09
- [PULL 06/17] .shippable: temporaily disable some cross builds, Alex Bennée, 2020/06/09
- [PULL 09/17] hw/virtio/vhost: re-factor vhost-section and allow DIRTY_MEMORY_CODE,
Alex Bennée <=
- [PULL 10/17] linux-user: provide fallback pgd_find_hole for bare chroots, Alex Bennée, 2020/06/09
- [PULL 08/17] docker: update Ubuntu to 20.04, Alex Bennée, 2020/06/09
- [PULL 11/17] linux-user: deal with address wrap for ARM_COMMPAGE on 32 bit, Alex Bennée, 2020/06/09
- [PULL 07/17] tests/docker: fix pre-requisite for debian-tricore-cross, Alex Bennée, 2020/06/09
- [PULL 15/17] tests/vm: Remove flex/bison packages, Alex Bennée, 2020/06/09
- [PULL 13/17] linux-user: detect overflow of MAP_FIXED mmap, Alex Bennée, 2020/06/09
- [PULL 17/17] scripts/coverity-scan: Remove flex/bison packages, Alex Bennée, 2020/06/09
- [PULL 14/17] tests/docker: Remove flex/bison packages, Alex Bennée, 2020/06/09