Only apply the workaround for broken slot joining in KVM when the capability was not found that signals the corresponding fix existence. Signed-off-by: Jan Kiszka --- kvm-all.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 32cd636..9e9b462 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -57,6 +57,7 @@ struct KVMState int fd; int vmfd; int coalesced_mmio; + int broken_set_mem_region; #ifdef KVM_CAP_SET_GUEST_DEBUG struct kvm_sw_breakpoint_head kvm_sw_breakpoints; #endif @@ -398,6 +399,14 @@ int kvm_init(int smp_cpus) s->coalesced_mmio = ret; #endif + s->broken_set_mem_region = 1; +#ifdef KVM_CAP_JOIN_MEMORY_REGIONS_WORKS + ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_JOIN_MEMORY_REGIONS_WORKS); + if (ret > 0) { + s->broken_set_mem_region = 0; + } +#endif + ret = kvm_arch_init(s, smp_cpus); if (ret < 0) goto err; @@ -623,7 +632,8 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, * address as the first existing one. If not or if some overlapping * slot comes around later, we will fail (not seen in practice so far) * - and actually require a recent KVM version. */ - if (old.start_addr == start_addr && old.memory_size < size && + if (s->broken_set_mem_region && + old.start_addr == start_addr && old.memory_size < size && flags < IO_MEM_UNASSIGNED) { mem = kvm_alloc_slot(s); mem->memory_size = old.memory_size;