#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
unsigned long *bitmap)
{
unsigned int i, j;
- unsigned long page_number, addr, addr1, c;
+ unsigned long page_number, c;
+ target_phys_addr_t addr, addr1;
unsigned int len = ((section->size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
/*
page_number = i * HOST_LONG_BITS + j;
addr1 = page_number * TARGET_PAGE_SIZE;
addr = section->offset_within_region + addr1;
- memory_region_set_dirty(section->mr, addr);
+ memory_region_set_dirty(section->mr, addr, TARGET_PAGE_SIZE);
} while (c != 0);
}
}
/**
* kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
- * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty().
- * This means all bits are set to dirty.
+ * This function updates qemu's dirty bitmap using
+ * memory_region_set_dirty(). This means all bits are set
+ * to dirty.
*
* @start_add: start of logged region.
* @end_addr: end of logged region.
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,
.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)
int kvm_has_gsi_routing(void)
{
+#ifdef KVM_CAP_IRQ_ROUTING
return kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING);
+#else
+ return false;
+#endif
}
int kvm_allows_irq0_override(void)