aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2012-09-30 22:21:11 +0200
committerAvi Kivity <avi@redhat.com>2012-09-30 22:21:11 +0200
commitebfb766a1a9bebf9ba828f4ac5124614c4a4f4ff (patch)
treebac5e01b296abdec68473711ead41737fe16d662
parent41d4b89a86dbf8e501fb5aa8a336823f2e205854 (diff)
kvm: use separate MemoryListeners for memory and I/O
The construct if (address_space == get_system_memory()) { // memory thing } else { // io thing } fails if we have more than two address spaces. Use a separate listener for memory and I/O, and utilize MemoryListener's address space filtering to fix this. Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--kvm-all.c83
1 files changed, 44 insertions, 39 deletions
diff --git a/kvm-all.c b/kvm-all.c
index 92a71374e..c69e01200 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -755,9 +755,16 @@ static void kvm_log_global_stop(struct MemoryListener *listener)
assert(r >= 0);
}
-static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
- bool match_data, uint64_t data, int fd)
+static void kvm_log_nop(struct MemoryListener *listener)
{
+}
+
+static void kvm_mem_ioeventfd_add(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e)
+{
+ int fd = event_notifier_get_fd(e);
int r;
assert(match_data && section->size <= 8);
@@ -769,9 +776,12 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
}
}
-static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
- bool match_data, uint64_t data, int fd)
+static void kvm_mem_ioeventfd_del(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e)
{
+ int fd = event_notifier_get_fd(e);
int r;
r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
@@ -781,9 +791,12 @@ static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
}
}
-static void kvm_io_ioeventfd_add(MemoryRegionSection *section,
- bool match_data, uint64_t data, int fd)
+static void kvm_io_ioeventfd_add(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e)
{
+ int fd = event_notifier_get_fd(e);
int r;
assert(match_data && section->size == 2);
@@ -795,10 +808,13 @@ static void kvm_io_ioeventfd_add(MemoryRegionSection *section,
}
}
-static void kvm_io_ioeventfd_del(MemoryRegionSection *section,
- bool match_data, uint64_t data, int fd)
+static void kvm_io_ioeventfd_del(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e)
{
+ int fd = event_notifier_get_fd(e);
int r;
r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
@@ -808,34 +824,6 @@ static void kvm_io_ioeventfd_del(MemoryRegionSection *section,
}
}
-static void kvm_eventfd_add(MemoryListener *listener,
- MemoryRegionSection *section,
- bool match_data, uint64_t data,
- EventNotifier *e)
-{
- if (section->address_space == get_system_memory()) {
- kvm_mem_ioeventfd_add(section, match_data, data,
- event_notifier_get_fd(e));
- } else {
- kvm_io_ioeventfd_add(section, match_data, data,
- event_notifier_get_fd(e));
- }
-}
-
-static void kvm_eventfd_del(MemoryListener *listener,
- MemoryRegionSection *section,
- bool match_data, uint64_t data,
- EventNotifier *e)
-{
- if (section->address_space == get_system_memory()) {
- kvm_mem_ioeventfd_del(section, match_data, data,
- event_notifier_get_fd(e));
- } else {
- kvm_io_ioeventfd_del(section, match_data, data,
- event_notifier_get_fd(e));
- }
-}
-
static MemoryListener kvm_memory_listener = {
.begin = kvm_begin,
.commit = kvm_commit,
@@ -847,8 +835,24 @@ static MemoryListener kvm_memory_listener = {
.log_sync = kvm_log_sync,
.log_global_start = kvm_log_global_start,
.log_global_stop = kvm_log_global_stop,
- .eventfd_add = kvm_eventfd_add,
- .eventfd_del = kvm_eventfd_del,
+ .eventfd_add = kvm_mem_ioeventfd_add,
+ .eventfd_del = kvm_mem_ioeventfd_del,
+ .priority = 10,
+};
+
+static MemoryListener kvm_io_listener = {
+ .begin = kvm_begin,
+ .commit = kvm_commit,
+ .region_add = kvm_region_nop,
+ .region_del = kvm_region_nop,
+ .region_nop = kvm_region_nop,
+ .log_start = kvm_region_nop,
+ .log_stop = kvm_region_nop,
+ .log_sync = kvm_region_nop,
+ .log_global_start = kvm_log_nop,
+ .log_global_stop = kvm_log_nop,
+ .eventfd_add = kvm_io_ioeventfd_add,
+ .eventfd_del = kvm_io_ioeventfd_del,
.priority = 10,
};
@@ -1401,7 +1405,8 @@ int kvm_init(void)
}
kvm_state = s;
- memory_listener_register(&kvm_memory_listener, NULL);
+ memory_listener_register(&kvm_memory_listener, get_system_memory());
+ memory_listener_register(&kvm_io_listener, get_system_io());
s->many_ioeventfds = kvm_check_many_ioeventfds();