summaryrefslogtreecommitdiff
path: root/kvm-all.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2012-02-08 16:39:06 +0200
committerAvi Kivity <avi@redhat.com>2012-02-29 13:44:41 +0200
commit80a1ea3748203b840d8bad488ada4d6f5bb66c9d (patch)
treeb29184d33c61b7cba42f44c3f6e03ff8f9640b61 /kvm-all.c
parent0e0d36b446bbe913edcf5a7af24590360845f824 (diff)
downloadqemu-80a1ea3748203b840d8bad488ada4d6f5bb66c9d.tar.gz
memory: move ioeventfd ops to MemoryListener
This way the accelerator (kvm) can handle them directly. Signed-off-by: Avi Kivity <avi@redhat.com> Reviewed-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'kvm-all.c')
-rw-r--r--kvm-all.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/kvm-all.c b/kvm-all.c
index 6835fd46f8..a05e591c59 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -28,6 +28,7 @@
#include "kvm.h"
#include "bswap.h"
#include "memory.h"
+#include "exec-memory.h"
/* This check must be after config-host.h is included */
#ifdef CONFIG_EVENTFD
@@ -718,6 +719,81 @@ 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)
+{
+ int r;
+
+ assert(match_data && section->size == 4);
+
+ r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
+ data, true);
+ if (r < 0) {
+ abort();
+ }
+}
+
+static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
+ bool match_data, uint64_t data, int fd)
+{
+ int r;
+
+ r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
+ data, false);
+ if (r < 0) {
+ abort();
+ }
+}
+
+static void kvm_io_ioeventfd_add(MemoryRegionSection *section,
+ bool match_data, uint64_t data, int fd)
+{
+ int r;
+
+ assert(match_data && section->size == 2);
+
+ r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
+ data, true);
+ if (r < 0) {
+ abort();
+ }
+}
+
+static void kvm_io_ioeventfd_del(MemoryRegionSection *section,
+ bool match_data, uint64_t data, int fd)
+
+{
+ int r;
+
+ r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
+ data, false);
+ if (r < 0) {
+ abort();
+ }
+}
+
+static void kvm_eventfd_add(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data, int fd)
+{
+ if (section->address_space == get_system_memory()) {
+ kvm_mem_ioeventfd_add(section, match_data, data, fd);
+ } else {
+ kvm_io_ioeventfd_add(section, match_data, data, fd);
+ }
+}
+
+static void kvm_eventfd_del(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data, int fd)
+{
+ if (section->address_space == get_system_memory()) {
+ kvm_mem_ioeventfd_del(section, match_data, data, fd);
+ } else {
+ kvm_io_ioeventfd_del(section, match_data, data, fd);
+ }
+}
+
static MemoryListener kvm_memory_listener = {
.region_add = kvm_region_add,
.region_del = kvm_region_del,
@@ -726,6 +802,8 @@ 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,
.priority = 10,
};