@@ -915,6 +915,8 @@ void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
+void qemu_flush_coalesced_mmio_buffer(void);
+
/*******************************************/
/* host CPU ticks (if available) */
@@ -2406,6 +2406,12 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
kvm_uncoalesce_mmio_region(addr, size);
}
+void qemu_flush_coalesced_mmio_buffer(void)
+{
+ if (kvm_enabled())
+ kvm_flush_coalesced_mmio_buffer();
+}
+
ram_addr_t qemu_ram_alloc(ram_addr_t size)
{
RAMBlock *new_block;
@@ -59,6 +59,9 @@ struct KVMState
int vmfd;
int regs_modified;
int coalesced_mmio;
+#ifdef KVM_CAP_COALESCED_MMIO
+ struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
+#endif
int broken_set_mem_region;
int migration_log;
int vcpu_events;
@@ -200,6 +203,12 @@ int kvm_init_vcpu(CPUState *env)
goto err;
}
+#ifdef KVM_CAP_COALESCED_MMIO
+ if (s->coalesced_mmio && !s->coalesced_mmio_ring)
+ s->coalesced_mmio_ring = (void *) env->kvm_run +
+ s->coalesced_mmio * PAGE_SIZE;
+#endif
+
ret = kvm_arch_init_vcpu(env);
if (ret == 0) {
qemu_register_reset(kvm_reset_vcpu, env);
@@ -466,10 +475,10 @@ int kvm_init(int smp_cpus)
goto err;
}
+ s->coalesced_mmio = 0;
#ifdef KVM_CAP_COALESCED_MMIO
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
-#else
- s->coalesced_mmio = 0;
+ s->coalesced_mmio_ring = NULL;
#endif
s->broken_set_mem_region = 1;
@@ -544,14 +553,12 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
return 1;
}
-static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
+void kvm_flush_coalesced_mmio_buffer(void)
{
#ifdef KVM_CAP_COALESCED_MMIO
KVMState *s = kvm_state;
- if (s->coalesced_mmio) {
- struct kvm_coalesced_mmio_ring *ring;
-
- ring = (void *)run + (s->coalesced_mmio * TARGET_PAGE_SIZE);
+ if (s->coalesced_mmio_ring) {
+ struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring;
while (ring->first != ring->last) {
struct kvm_coalesced_mmio *ent;
@@ -609,7 +616,7 @@ int kvm_cpu_exec(CPUState *env)
abort();
}
- kvm_run_coalesced_mmio(env, run);
+ kvm_flush_coalesced_mmio_buffer();
ret = 0; /* exit loop */
switch (run->exit_reason) {
@@ -53,6 +53,7 @@ void kvm_setup_guest_memory(void *start, size_t size);
int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
+void kvm_flush_coalesced_mmio_buffer(void);
int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
target_ulong len, int type);
@@ -2996,6 +2996,7 @@ static void gui_update(void *opaque)
DisplayState *ds = opaque;
DisplayChangeListener *dcl = ds->listeners;
+ qemu_flush_coalesced_mmio_buffer();
dpy_refresh(ds);
while (dcl != NULL) {
@@ -3011,6 +3012,7 @@ static void nographic_update(void *opaque)
{
uint64_t interval = GUI_REFRESH_INTERVAL;
+ qemu_flush_coalesced_mmio_buffer();
qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
}