Until now, KVM_SET_USER_MEMORY_REGION has been working on address_space_memory. However, KVM's memory slots are the CPU view of the memory, which does not exactly match address_space_memory.
Let the architecture-specific code build the CPU view of the memory by combining address_space_memory and other MemoryRegions. Signed-off-by: Paolo Bonzini <[email protected]> --- include/sysemu/kvm_int.h | 3 +++ kvm-all.c | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index d5f746f..5e4090d 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -60,6 +60,9 @@ struct KVMState QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; bool direct_msi; #endif + + AddressSpace kvm_as; + MemoryRegion kvm_as_root, kvm_as_mem; }; #define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm") diff --git a/kvm-all.c b/kvm-all.c index 215ed33..c70436e 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1401,6 +1401,7 @@ static int kvm_init(MachineState *ms) const char *kvm_type; s = KVM_STATE(ms->accelerator); + kvm_state = s; /* * On systems where the kernel can support different base page @@ -1578,9 +1579,21 @@ static int kvm_init(MachineState *ms) kvm_vm_attributes_allowed = (kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES) > 0); + /* An outer container, with normal system memory inside. + * kvm_arch_init can add more. + */ + memory_region_init(&s->kvm_as_root, OBJECT(s), "mem-container", ~0ull); + memory_region_set_enabled(&s->kvm_as_root, true); + memory_region_init_alias(&s->kvm_as_mem, OBJECT(s), "memory", + get_system_memory(), 0, ~0ull); + memory_region_set_enabled(&s->kvm_as_mem, true); + memory_region_add_subregion_overlap(&s->kvm_as_root, 0, &s->kvm_as_mem, 0); + + address_space_init(&s->kvm_as, &s->kvm_as_root, "KVM"); + ret = kvm_arch_init(ms, s); if (ret < 0) { - goto err; + goto err_as_destroy; } ret = kvm_irqchip_create(ms, s); @@ -1588,8 +1601,7 @@ static int kvm_init(MachineState *ms) goto err; } - kvm_state = s; - memory_listener_register(&kvm_memory_listener, &address_space_memory); + memory_listener_register(&kvm_memory_listener, &s->kvm_as); memory_listener_register(&kvm_io_listener, &address_space_io); s->many_ioeventfds = kvm_check_many_ioeventfds(); @@ -1598,6 +1610,8 @@ static int kvm_init(MachineState *ms) return 0; +err_as_destroy: + address_space_destroy(&s->kvm_as); err: assert(ret < 0); if (s->vmfd >= 0) { @@ -1607,6 +1621,7 @@ err: close(s->fd); } g_free(s->slots); + kvm_state = NULL; return ret; } -- 1.8.3.1
