diff --git a/exec.c b/exec.c index 2effd04f62..c64938124b 100644 --- a/exec.c +++ b/exec.c @@ -2484,6 +2484,9 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size) last_ram_offset += size; + if (kvm_enabled()) + kvm_setup_guest_memory(new_block->host, size); + return new_block->offset; } diff --git a/kvm-all.c b/kvm-all.c index 0da5c7aa8d..36659a95e8 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -773,6 +773,24 @@ int kvm_has_sync_mmu(void) return 0; } +void kvm_setup_guest_memory(void *start, size_t size) +{ + if (!kvm_has_sync_mmu()) { +#ifdef MADV_DONTFORK + int ret = madvise(start, size, MADV_DONTFORK); + + if (ret) { + perror("madvice"); + exit(1); + } +#else + fprintf(stderr, + "Need MADV_DONTFORK in absence of synchronous KVM MMU\n"); + exit(1); +#endif + } +} + #ifdef KVM_CAP_SET_GUEST_DEBUG struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env, target_ulong pc) diff --git a/kvm.h b/kvm.h index 803a874113..0ea24266be 100644 --- a/kvm.h +++ b/kvm.h @@ -48,6 +48,8 @@ int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size); int kvm_has_sync_mmu(void); +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);