Commit e69917e29acc6a21a15c5c6b5569333ddf384a38

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent 73c632ed

kvm: Conditionally apply workaround for KVM slot handling bug

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 <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 1 changed file with 11 additions and 1 deletions
kvm-all.c
@@ -57,6 +57,7 @@ struct KVMState @@ -57,6 +57,7 @@ struct KVMState
57 int fd; 57 int fd;
58 int vmfd; 58 int vmfd;
59 int coalesced_mmio; 59 int coalesced_mmio;
  60 + int broken_set_mem_region;
60 #ifdef KVM_CAP_SET_GUEST_DEBUG 61 #ifdef KVM_CAP_SET_GUEST_DEBUG
61 struct kvm_sw_breakpoint_head kvm_sw_breakpoints; 62 struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
62 #endif 63 #endif
@@ -406,6 +407,14 @@ int kvm_init(int smp_cpus) @@ -406,6 +407,14 @@ int kvm_init(int smp_cpus)
406 s->coalesced_mmio = 0; 407 s->coalesced_mmio = 0;
407 #endif 408 #endif
408 409
  410 + s->broken_set_mem_region = 1;
  411 +#ifdef KVM_CAP_JOIN_MEMORY_REGIONS_WORKS
  412 + ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_JOIN_MEMORY_REGIONS_WORKS);
  413 + if (ret > 0) {
  414 + s->broken_set_mem_region = 0;
  415 + }
  416 +#endif
  417 +
409 ret = kvm_arch_init(s, smp_cpus); 418 ret = kvm_arch_init(s, smp_cpus);
410 if (ret < 0) 419 if (ret < 0)
411 goto err; 420 goto err;
@@ -639,7 +648,8 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, @@ -639,7 +648,8 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr,
639 * address as the first existing one. If not or if some overlapping 648 * address as the first existing one. If not or if some overlapping
640 * slot comes around later, we will fail (not seen in practice so far) 649 * slot comes around later, we will fail (not seen in practice so far)
641 * - and actually require a recent KVM version. */ 650 * - and actually require a recent KVM version. */
642 - if (old.start_addr == start_addr && old.memory_size < size && 651 + if (s->broken_set_mem_region &&
  652 + old.start_addr == start_addr && old.memory_size < size &&
643 flags < IO_MEM_UNASSIGNED) { 653 flags < IO_MEM_UNASSIGNED) {
644 mem = kvm_alloc_slot(s); 654 mem = kvm_alloc_slot(s);
645 mem->memory_size = old.memory_size; 655 mem->memory_size = old.memory_size;