diff options
author | Avi Kivity <avi@redhat.com> | 2012-02-08 16:39:06 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-02-29 13:44:41 +0200 |
commit | 80a1ea3748203b840d8bad488ada4d6f5bb66c9d (patch) | |
tree | b29184d33c61b7cba42f44c3f6e03ff8f9640b61 /kvm-all.c | |
parent | 0e0d36b446bbe913edcf5a7af24590360845f824 (diff) | |
download | qemu-80a1ea3748203b840d8bad488ada4d6f5bb66c9d.zip qemu-80a1ea3748203b840d8bad488ada4d6f5bb66c9d.tar.gz qemu-80a1ea3748203b840d8bad488ada4d6f5bb66c9d.tar.bz2 |
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.c | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -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, }; |