On 18/07/19 09:21, Alexey Kardashevskiy wrote: > Paolo, ping? :) Queued, thanks. I'll sneak it into 4.1, I have a couple other patches to send.
Paolo > > On 14/06/2019 11:52, Alexey Kardashevskiy wrote: >> This adds an accelerator name to the "into mtree -f" to tell the user if >> a particular memory section is registered with the accelerator; >> the primary user for this is KVM and such information is useful >> for debugging purposes. >> >> This adds a has_memory() callback to the accelerator class allowing any >> accelerator to have a label in that memory tree dump. >> >> Since memory sections are passed to memory listeners and get registered >> in accelerators (rather than memory regions), this only prints new labels >> for flatviews attached to the system address space. >> >> An example: >> Root memory region: system >> 0000000000000000-0000002fffffffff (prio 0, ram): /objects/mem0 kvm >> 0000003000000000-0000005fffffffff (prio 0, ram): /objects/mem1 kvm >> 0000200000000020-000020000000003f (prio 1, i/o): virtio-pci >> 0000200080000000-000020008000003f (prio 0, i/o): capabilities >> >> Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> >> --- >> Changes: >> v3: >> * added support for multiple ASes per accelerator (KVM can do 2 at least) >> as Paolo suggested >> >> v2: >> * added an accelerator callback instead of hardcoding it to kvm only >> --- >> include/sysemu/accel.h | 3 +++ >> accel/kvm/kvm-all.c | 38 ++++++++++++++++++++++++++++++++++++++ >> memory.c | 22 ++++++++++++++++++++++ >> 3 files changed, 63 insertions(+) >> >> diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h >> index 81293cdb08f9..89ce57e404ca 100644 >> --- a/include/sysemu/accel.h >> +++ b/include/sysemu/accel.h >> @@ -25,6 +25,7 @@ >> #include "qom/object.h" >> #include "hw/qdev-properties.h" >> +#include "exec/hwaddr.h" >> typedef struct AccelState { >> /*< private >*/ >> @@ -39,6 +40,8 @@ typedef struct AccelClass { >> const char *name; >> int (*init_machine)(MachineState *ms); >> void (*setup_post)(MachineState *ms, AccelState *accel); >> + bool (*has_memory)(MachineState *ms, AddressSpace *as, >> + hwaddr start_addr, hwaddr size); >> bool *allowed; >> /* >> * Array of global properties that would be applied when specific >> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c >> index b0c4bed6e367..948b7e53df47 100644 >> --- a/accel/kvm/kvm-all.c >> +++ b/accel/kvm/kvm-all.c >> @@ -109,6 +109,13 @@ struct KVMState >> /* memory encryption */ >> void *memcrypt_handle; >> int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, >> uint64_t len); >> + >> + /* For "info mtree -f" to tell if an MR is registered in KVM */ >> + int nr_as; >> + struct KVMAs { >> + KVMMemoryListener *ml; >> + AddressSpace *as; >> + } *as; >> }; >> KVMState *kvm_state; >> @@ -940,6 +947,14 @@ void kvm_memory_listener_register(KVMState *s, >> KVMMemoryListener *kml, >> kml->listener.priority = 10; >> memory_listener_register(&kml->listener, as); >> + >> + for (i = 0; i < s->nr_as; ++i) { >> + if (!s->as[i].as) { >> + s->as[i].as = as; >> + s->as[i].ml = kml; >> + break; >> + } >> + } >> } >> static MemoryListener kvm_io_listener = { >> @@ -1590,6 +1605,12 @@ static int kvm_init(MachineState *ms) >> s->nr_slots = 32; >> } >> + s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE); >> + if (s->nr_as <= 1) { >> + s->nr_as = 1; >> + } >> + s->as = g_new0(struct KVMAs, s->nr_as); >> + >> kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type"); >> if (mc->kvm_type) { >> type = mc->kvm_type(ms, kvm_type); >> @@ -2591,11 +2612,28 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, >> void *target) >> return r; >> } >> +static bool kvm_accel_has_memory(MachineState *ms, AddressSpace *as, >> + hwaddr start_addr, hwaddr size) >> +{ >> + KVMState *kvm = KVM_STATE(ms->accelerator); >> + int i; >> + >> + for (i = 0; i < kvm->nr_as; ++i) { >> + if (kvm->as[i].as == as && kvm->as[i].ml) { >> + return NULL != kvm_lookup_matching_slot(kvm->as[i].ml, >> + start_addr, size); >> + } >> + } >> + >> + return false; >> +} >> + >> static void kvm_accel_class_init(ObjectClass *oc, void *data) >> { >> AccelClass *ac = ACCEL_CLASS(oc); >> ac->name = "KVM"; >> ac->init_machine = kvm_init; >> + ac->has_memory = kvm_accel_has_memory; >> ac->allowed = &kvm_allowed; >> } >> diff --git a/memory.c b/memory.c >> index 0a089a73ae1a..61524156a1ce 100644 >> --- a/memory.c >> +++ b/memory.c >> @@ -30,7 +30,9 @@ >> #include "sysemu/kvm.h" >> #include "sysemu/sysemu.h" >> #include "sysemu/tcg.h" >> +#include "sysemu/accel.h" >> #include "hw/qdev-properties.h" >> +#include "hw/boards.h" >> #include "migration/vmstate.h" >> //#define DEBUG_UNASSIGNED >> @@ -2939,6 +2941,8 @@ struct FlatViewInfo { >> int counter; >> bool dispatch_tree; >> bool owner; >> + AccelClass *ac; >> + const char *ac_name; >> }; >> static void mtree_print_flatview(gpointer key, gpointer value, >> @@ -3001,6 +3005,17 @@ static void mtree_print_flatview(gpointer key, >> gpointer value, >> if (fvi->owner) { >> mtree_print_mr_owner(mr); >> } >> + >> + if (fvi->ac) { >> + for (i = 0; i < fv_address_spaces->len; ++i) { >> + as = g_array_index(fv_address_spaces, AddressSpace*, i); >> + if (fvi->ac->has_memory(current_machine, as, >> + int128_get64(range->addr.start), >> + MR_SIZE(range->addr.size) + >> 1)) { >> + qemu_printf(" %s", fvi->ac_name); >> + } >> + } >> + } >> qemu_printf("\n"); >> range++; >> } >> @@ -3041,6 +3056,13 @@ void mtree_info(bool flatview, bool >> dispatch_tree, bool owner) >> }; >> GArray *fv_address_spaces; >> GHashTable *views = g_hash_table_new(g_direct_hash, >> g_direct_equal); >> + AccelClass *ac = ACCEL_GET_CLASS(current_machine->accelerator); >> + >> + if (ac->has_memory) { >> + fvi.ac = ac; >> + fvi.ac_name = current_machine->accel ? >> current_machine->accel : >> + object_class_get_name(OBJECT_CLASS(ac)); >> + } >> /* Gather all FVs in one table */ >> QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { >> >