diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-01 15:26:25 -0600 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-01 15:26:25 -0600 |
commit | 14655e482bc9ef44b841bdca55d79ab0891058e9 (patch) | |
tree | 9c15043de37ef4943b9ebd265455c09cfad253e2 /kvm-all.c | |
parent | 5918ff68ff3ffe61ae8ebff5b031d6bdcc63c6bc (diff) | |
parent | 07f07b31e57efa6e4f563802136ffa1694a2692b (diff) | |
download | qemu-14655e482bc9ef44b841bdca55d79ab0891058e9.tar.gz qemu-14655e482bc9ef44b841bdca55d79ab0891058e9.tar.bz2 qemu-14655e482bc9ef44b841bdca55d79ab0891058e9.zip |
Merge remote-tracking branch 'qemu-kvm/memory/core' into staging
* qemu-kvm/memory/core: (30 commits)
memory: allow phys_map tree paths to terminate early
memory: unify PhysPageEntry::node and ::leaf
memory: change phys_page_set() to set multiple pages
memory: switch phys_page_set() to a recursive implementation
memory: replace phys_page_find_alloc() with phys_page_set()
memory: simplify multipage/subpage registration
memory: give phys_page_find() its own tree search loop
memory: make phys_page_find() return a MemoryRegionSection
memory: move tlb flush to MemoryListener commit callback
memory: unify the two branches of cpu_register_physical_memory_log()
memory: fix RAM subpages in newly initialized pages
memory: compress phys_map node pointers to 16 bits
memory: store MemoryRegionSection pointers in phys_map
memory: unify phys_map last level with intermediate levels
memory: remove first level of l1_phys_map
memory: change memory registration to rebuild the memory map on each change
memory: support stateless memory listeners
memory: split memory listener for the two address spaces
xen: ignore I/O memory regions
memory: allow MemoryListeners to observe a specific address space
...
Diffstat (limited to 'kvm-all.c')
-rw-r--r-- | kvm-all.c | 97 |
1 files changed, 96 insertions, 1 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 @@ -674,6 +675,14 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add) } } +static void kvm_begin(MemoryListener *listener) +{ +} + +static void kvm_commit(MemoryListener *listener) +{ +} + static void kvm_region_add(MemoryListener *listener, MemoryRegionSection *section) { @@ -686,6 +695,11 @@ static void kvm_region_del(MemoryListener *listener, kvm_set_phys_mem(section, false); } +static void kvm_region_nop(MemoryListener *listener, + MemoryRegionSection *section) +{ +} + static void kvm_log_sync(MemoryListener *listener, MemoryRegionSection *section) { @@ -713,14 +727,95 @@ 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 = { + .begin = kvm_begin, + .commit = kvm_commit, .region_add = kvm_region_add, .region_del = kvm_region_del, + .region_nop = kvm_region_nop, .log_start = kvm_log_start, .log_stop = kvm_log_stop, .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, }; static void kvm_handle_interrupt(CPUState *env, int mask) @@ -965,7 +1060,7 @@ int kvm_init(void) } kvm_state = s; - memory_listener_register(&kvm_memory_listener); + memory_listener_register(&kvm_memory_listener, NULL); s->many_ioeventfds = kvm_check_many_ioeventfds(); |