[PATCH 7/7] system/memory: Have 'info mtree' display addresses nicely

Philippe Mathieu-Daudé posted 7 patches 3 days, 10 hours ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Peter Xu <peterx@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
[PATCH 7/7] system/memory: Have 'info mtree' display addresses nicely
Posted by Philippe Mathieu-Daudé 3 days, 10 hours ago
Use the size of a MR / AS to decide how many address chars
need to be used.

For example, using 'qemu-system-x86_64 -M q35 -S -monitor stdio'
to run 'info mtree' displays before:

  address-space: I/O
    0000000000000000-000000000000ffff (prio 0, i/o): io
        0000000000000000-0000000000000003 (prio 0, i/o): acpi-evt
        0000000000000004-0000000000000005 (prio 0, i/o): acpi-cnt
        0000000000000008-000000000000000b (prio 0, i/o): acpi-tmr
        0000000000000020-000000000000002f (prio 0, i/o): acpi-gpe0
        0000000000000030-0000000000000037 (prio 0, i/o): acpi-smi
        0000000000000060-000000000000007f (prio 0, i/o): sm-tco
      0000000000000000-0000000000000007 (prio 0, i/o): dma-chan
      0000000000000008-000000000000000f (prio 0, i/o): dma-cont
      0000000000000020-0000000000000021 (prio 0, i/o): pic
      0000000000000040-0000000000000043 (prio 0, i/o): pit
      ...
  memory-region: pc.ram
    0000000000000000-0000000007ffffff (prio 0, ram): pc.ram
  memory-region: pc.bios
    00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
  memory-region: pci
    0000000000000000-ffffffffffffffff (prio -1, i/o): pci
      00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
      00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
      00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
      00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
  ...

and after:

  address-space: I/O
    0000-ffff (prio 0, container): io
        0000-0003 (prio 0, i/o): acpi-evt
        0004-0005 (prio 0, i/o): acpi-cnt
        0008-000b (prio 0, i/o): acpi-tmr
        0020-002f (prio 0, i/o): acpi-gpe0
        0030-0037 (prio 0, i/o): acpi-smi
        0060-007f (prio 0, i/o): sm-tco
      0000-0007 (prio 0, i/o): dma-chan
      0008-000f (prio 0, i/o): dma-cont
      0020-0021 (prio 0, i/o): pic
      0040-0043 (prio 0, i/o): pit
      ...
  memory-region: pc.ram
    00000000-07ffffff (prio 0, ram): pc.ram
  memory-region: pc.bios
    fffc0000-ffffffff (prio 0, rom): pc.bios
  memory-region: pci
    0000000000000000-ffffffffffffffff (prio -1, i/o): pci
      00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
      00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
      00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
      00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
  ...

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 system/memory.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/system/memory.c b/system/memory.c
index 4d276307da5..abcbdaadcd7 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -3321,7 +3321,26 @@ typedef QTAILQ_HEAD(, MemoryRegionList) MemoryRegionListHead;
 
 #define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
                            int128_sub((size), int128_one())) : 0)
-#define MR_ADDR_WIDTH   16
+
+static unsigned mr_addr_fmt_width(const MemoryRegion *mr)
+{
+    const unsigned int bits = 127 - clz128(mr->size);
+    unsigned int width;
+
+    if (bits <= 8) {
+        width = 2;
+    } else if (bits <= 16) {
+        width = 4;
+    } else if (bits <= 32) {
+        width = 8;
+    } else if (bits <= 64) {
+        width = 16;
+    } else {
+        width = 20;
+    }
+    return width;
+}
+
 #define MTREE_INDENT "  "
 
 static void mtree_expand_owner(const char *label, Object *obj)
@@ -3513,7 +3532,7 @@ static void mtree_print_flatview(gpointer key, gpointer value,
         return;
     }
 
-    width = MR_ADDR_WIDTH;
+    width = mr_addr_fmt_width(view->root);
     while (n--) {
         const MemoryRegion *mr = range->mr;
 
@@ -3643,7 +3662,7 @@ static void mtree_print_as(gpointer key, gpointer value, gpointer user_data)
     MemoryRegion *mr = key;
     GSList *as_same_root_mr_list = value;
     struct AddressSpaceInfo *asi = user_data;
-    const unsigned int width = MR_ADDR_WIDTH;
+    const unsigned int width = mr_addr_fmt_width(mr);
 
     g_slist_foreach(as_same_root_mr_list, mtree_print_as_name, NULL);
     mtree_print_mr(mr, 1, width, -mr->addr, false,
@@ -3692,7 +3711,7 @@ static void mtree_info_as(bool dispatch_tree, bool owner, bool disabled)
     /* print aliased regions */
     QTAILQ_FOREACH(ml, &ml_head, mrqueue) {
         const MemoryRegion *mr = ml->mr;
-        const unsigned int width = MR_ADDR_WIDTH;
+        const unsigned int width = mr_addr_fmt_width(mr);
 
         qemu_printf("memory-region: %s\n", memory_region_name(mr));
         mtree_print_mr(mr, 1, width, 0, false, &ml_head, owner, disabled);
-- 
2.52.0


Re: [PATCH 7/7] system/memory: Have 'info mtree' display addresses nicely
Posted by BALATON Zoltan 3 days, 10 hours ago
On Thu, 26 Feb 2026, Philippe Mathieu-Daudé wrote:
> Use the size of a MR / AS to decide how many address chars
> need to be used.
>
> For example, using 'qemu-system-x86_64 -M q35 -S -monitor stdio'
> to run 'info mtree' displays before:
>
>  address-space: I/O
>    0000000000000000-000000000000ffff (prio 0, i/o): io
>        0000000000000000-0000000000000003 (prio 0, i/o): acpi-evt
>        0000000000000004-0000000000000005 (prio 0, i/o): acpi-cnt
>        0000000000000008-000000000000000b (prio 0, i/o): acpi-tmr
>        0000000000000020-000000000000002f (prio 0, i/o): acpi-gpe0
>        0000000000000030-0000000000000037 (prio 0, i/o): acpi-smi
>        0000000000000060-000000000000007f (prio 0, i/o): sm-tco
>      0000000000000000-0000000000000007 (prio 0, i/o): dma-chan
>      0000000000000008-000000000000000f (prio 0, i/o): dma-cont
>      0000000000000020-0000000000000021 (prio 0, i/o): pic
>      0000000000000040-0000000000000043 (prio 0, i/o): pit
>      ...
>  memory-region: pc.ram
>    0000000000000000-0000000007ffffff (prio 0, ram): pc.ram
>  memory-region: pc.bios
>    00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>  memory-region: pci
>    0000000000000000-ffffffffffffffff (prio -1, i/o): pci
>      00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
>      00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
>      00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
>      00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>  ...
>
> and after:
>
>  address-space: I/O
>    0000-ffff (prio 0, container): io
>        0000-0003 (prio 0, i/o): acpi-evt
>        0004-0005 (prio 0, i/o): acpi-cnt
>        0008-000b (prio 0, i/o): acpi-tmr
>        0020-002f (prio 0, i/o): acpi-gpe0
>        0030-0037 (prio 0, i/o): acpi-smi
>        0060-007f (prio 0, i/o): sm-tco
>      0000-0007 (prio 0, i/o): dma-chan
>      0008-000f (prio 0, i/o): dma-cont
>      0020-0021 (prio 0, i/o): pic
>      0040-0043 (prio 0, i/o): pit
>      ...
>  memory-region: pc.ram
>    00000000-07ffffff (prio 0, ram): pc.ram
>  memory-region: pc.bios
>    fffc0000-ffffffff (prio 0, rom): pc.bios
>  memory-region: pci
>    0000000000000000-ffffffffffffffff (prio -1, i/o): pci
>      00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
>      00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
>      00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
>      00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>  ...
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
> system/memory.c | 27 +++++++++++++++++++++++----
> 1 file changed, 23 insertions(+), 4 deletions(-)
>
> diff --git a/system/memory.c b/system/memory.c
> index 4d276307da5..abcbdaadcd7 100644
> --- a/system/memory.c
> +++ b/system/memory.c
> @@ -3321,7 +3321,26 @@ typedef QTAILQ_HEAD(, MemoryRegionList) MemoryRegionListHead;
>
> #define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
>                            int128_sub((size), int128_one())) : 0)
> -#define MR_ADDR_WIDTH   16
> +
> +static unsigned mr_addr_fmt_width(const MemoryRegion *mr)
> +{
> +    const unsigned int bits = 127 - clz128(mr->size);
> +    unsigned int width;
> +
> +    if (bits <= 8) {
> +        width = 2;
> +    } else if (bits <= 16) {
> +        width = 4;
> +    } else if (bits <= 32) {
> +        width = 8;
> +    } else if (bits <= 64) {
> +        width = 16;
> +    } else {
> +        width = 20;

Why 20? HWADDR_FMT_plx this seems to replace is "%016" PRIx64

Regards,
BALATON Zoltan

> +    }
> +    return width;
> +}
> +
> #define MTREE_INDENT "  "
>
> static void mtree_expand_owner(const char *label, Object *obj)
> @@ -3513,7 +3532,7 @@ static void mtree_print_flatview(gpointer key, gpointer value,
>         return;
>     }
>
> -    width = MR_ADDR_WIDTH;
> +    width = mr_addr_fmt_width(view->root);
>     while (n--) {
>         const MemoryRegion *mr = range->mr;
>
> @@ -3643,7 +3662,7 @@ static void mtree_print_as(gpointer key, gpointer value, gpointer user_data)
>     MemoryRegion *mr = key;
>     GSList *as_same_root_mr_list = value;
>     struct AddressSpaceInfo *asi = user_data;
> -    const unsigned int width = MR_ADDR_WIDTH;
> +    const unsigned int width = mr_addr_fmt_width(mr);
>
>     g_slist_foreach(as_same_root_mr_list, mtree_print_as_name, NULL);
>     mtree_print_mr(mr, 1, width, -mr->addr, false,
> @@ -3692,7 +3711,7 @@ static void mtree_info_as(bool dispatch_tree, bool owner, bool disabled)
>     /* print aliased regions */
>     QTAILQ_FOREACH(ml, &ml_head, mrqueue) {
>         const MemoryRegion *mr = ml->mr;
> -        const unsigned int width = MR_ADDR_WIDTH;
> +        const unsigned int width = mr_addr_fmt_width(mr);
>
>         qemu_printf("memory-region: %s\n", memory_region_name(mr));
>         mtree_print_mr(mr, 1, width, 0, false, &ml_head, owner, disabled);
>
Re: [PATCH 7/7] system/memory: Have 'info mtree' display addresses nicely
Posted by Philippe Mathieu-Daudé 2 days, 16 hours ago
Hi Zoltan,

On 26/2/26 23:35, BALATON Zoltan wrote:
> On Thu, 26 Feb 2026, Philippe Mathieu-Daudé wrote:
>> Use the size of a MR / AS to decide how many address chars
>> need to be used.
>>
>> For example, using 'qemu-system-x86_64 -M q35 -S -monitor stdio'
>> to run 'info mtree' displays before:
>>
>>  address-space: I/O
>>    0000000000000000-000000000000ffff (prio 0, i/o): io
>>        0000000000000000-0000000000000003 (prio 0, i/o): acpi-evt
>>        0000000000000004-0000000000000005 (prio 0, i/o): acpi-cnt
>>        0000000000000008-000000000000000b (prio 0, i/o): acpi-tmr
>>        0000000000000020-000000000000002f (prio 0, i/o): acpi-gpe0
>>        0000000000000030-0000000000000037 (prio 0, i/o): acpi-smi
>>        0000000000000060-000000000000007f (prio 0, i/o): sm-tco
>>      0000000000000000-0000000000000007 (prio 0, i/o): dma-chan
>>      0000000000000008-000000000000000f (prio 0, i/o): dma-cont
>>      0000000000000020-0000000000000021 (prio 0, i/o): pic
>>      0000000000000040-0000000000000043 (prio 0, i/o): pit
>>      ...
>>  memory-region: pc.ram
>>    0000000000000000-0000000007ffffff (prio 0, ram): pc.ram
>>  memory-region: pc.bios
>>    00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>>  memory-region: pci
>>    0000000000000000-ffffffffffffffff (prio -1, i/o): pci
>>      00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
>>      00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
>>      00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios 
>> @pc.bios 0000000000020000-000000000003ffff
>>      00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>>  ...
>>
>> and after:
>>
>>  address-space: I/O
>>    0000-ffff (prio 0, container): io
>>        0000-0003 (prio 0, i/o): acpi-evt
>>        0004-0005 (prio 0, i/o): acpi-cnt
>>        0008-000b (prio 0, i/o): acpi-tmr
>>        0020-002f (prio 0, i/o): acpi-gpe0
>>        0030-0037 (prio 0, i/o): acpi-smi
>>        0060-007f (prio 0, i/o): sm-tco
>>      0000-0007 (prio 0, i/o): dma-chan
>>      0008-000f (prio 0, i/o): dma-cont
>>      0020-0021 (prio 0, i/o): pic
>>      0040-0043 (prio 0, i/o): pit
>>      ...
>>  memory-region: pc.ram
>>    00000000-07ffffff (prio 0, ram): pc.ram
>>  memory-region: pc.bios
>>    fffc0000-ffffffff (prio 0, rom): pc.bios
>>  memory-region: pci
>>    0000000000000000-ffffffffffffffff (prio -1, i/o): pci
>>      00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
>>      00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
>>      00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios 
>> @pc.bios 0000000000020000-000000000003ffff
>>      00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>>  ...
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> ---
>> system/memory.c | 27 +++++++++++++++++++++++----
>> 1 file changed, 23 insertions(+), 4 deletions(-)
>>
>> diff --git a/system/memory.c b/system/memory.c
>> index 4d276307da5..abcbdaadcd7 100644
>> --- a/system/memory.c
>> +++ b/system/memory.c
>> @@ -3321,7 +3321,26 @@ typedef QTAILQ_HEAD(, MemoryRegionList) 
>> MemoryRegionListHead;
>>
>> #define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
>>                            int128_sub((size), int128_one())) : 0)
>> -#define MR_ADDR_WIDTH   16
>> +
>> +static unsigned mr_addr_fmt_width(const MemoryRegion *mr)
>> +{
>> +    const unsigned int bits = 127 - clz128(mr->size);
>> +    unsigned int width;
>> +
>> +    if (bits <= 8) {
>> +        width = 2;
>> +    } else if (bits <= 16) {
>> +        width = 4;
>> +    } else if (bits <= 32) {
>> +        width = 8;
>> +    } else if (bits <= 64) {
>> +        width = 16;
>> +    } else {
>> +        width = 20;
> 
> Why 20? HWADDR_FMT_plx this seems to replace is "%016" PRIx64

HWADDR_FMT_plx predates support for int128_t and 128-bit wide
addresses. Using 20 chars is sufficient to align our current
uses.

I'll precise that in the patch description.

Regards,

Phil.

> 
> Regards,
> BALATON Zoltan


Re: [PATCH 7/7] system/memory: Have 'info mtree' display addresses nicely
Posted by Pierrick Bouvier 3 days, 10 hours ago
On 2/26/26 2:02 PM, Philippe Mathieu-Daudé wrote:
> Use the size of a MR / AS to decide how many address chars
> need to be used.
> 
> For example, using 'qemu-system-x86_64 -M q35 -S -monitor stdio'
> to run 'info mtree' displays before:
> 
>    address-space: I/O
>      0000000000000000-000000000000ffff (prio 0, i/o): io
>          0000000000000000-0000000000000003 (prio 0, i/o): acpi-evt
>          0000000000000004-0000000000000005 (prio 0, i/o): acpi-cnt
>          0000000000000008-000000000000000b (prio 0, i/o): acpi-tmr
>          0000000000000020-000000000000002f (prio 0, i/o): acpi-gpe0
>          0000000000000030-0000000000000037 (prio 0, i/o): acpi-smi
>          0000000000000060-000000000000007f (prio 0, i/o): sm-tco
>        0000000000000000-0000000000000007 (prio 0, i/o): dma-chan
>        0000000000000008-000000000000000f (prio 0, i/o): dma-cont
>        0000000000000020-0000000000000021 (prio 0, i/o): pic
>        0000000000000040-0000000000000043 (prio 0, i/o): pit
>        ...
>    memory-region: pc.ram
>      0000000000000000-0000000007ffffff (prio 0, ram): pc.ram
>    memory-region: pc.bios
>      00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>    memory-region: pci
>      0000000000000000-ffffffffffffffff (prio -1, i/o): pci
>        00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
>        00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
>        00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
>        00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>    ...
> 
> and after:
> 
>    address-space: I/O
>      0000-ffff (prio 0, container): io
>          0000-0003 (prio 0, i/o): acpi-evt
>          0004-0005 (prio 0, i/o): acpi-cnt
>          0008-000b (prio 0, i/o): acpi-tmr
>          0020-002f (prio 0, i/o): acpi-gpe0
>          0030-0037 (prio 0, i/o): acpi-smi
>          0060-007f (prio 0, i/o): sm-tco
>        0000-0007 (prio 0, i/o): dma-chan
>        0008-000f (prio 0, i/o): dma-cont
>        0020-0021 (prio 0, i/o): pic
>        0040-0043 (prio 0, i/o): pit
>        ...
>    memory-region: pc.ram
>      00000000-07ffffff (prio 0, ram): pc.ram
>    memory-region: pc.bios
>      fffc0000-ffffffff (prio 0, rom): pc.bios
>    memory-region: pci
>      0000000000000000-ffffffffffffffff (prio -1, i/o): pci
>        00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
>        00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
>        00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
>        00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
>    ...
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   system/memory.c | 27 +++++++++++++++++++++++----
>   1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/system/memory.c b/system/memory.c
> index 4d276307da5..abcbdaadcd7 100644
> --- a/system/memory.c
> +++ b/system/memory.c
> @@ -3321,7 +3321,26 @@ typedef QTAILQ_HEAD(, MemoryRegionList) MemoryRegionListHead;
>   
>   #define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
>                              int128_sub((size), int128_one())) : 0)
> -#define MR_ADDR_WIDTH   16
> +
> +static unsigned mr_addr_fmt_width(const MemoryRegion *mr)
> +{
> +    const unsigned int bits = 127 - clz128(mr->size);
> +    unsigned int width;
> +
> +    if (bits <= 8) {
> +        width = 2;
> +    } else if (bits <= 16) {
> +        width = 4;
> +    } else if (bits <= 32) {
> +        width = 8;
> +    } else if (bits <= 64) {
> +        width = 16;
> +    } else {
> +        width = 20;
> +    }
> +    return width;
> +}
> +
>   #define MTREE_INDENT "  "
>   
>   static void mtree_expand_owner(const char *label, Object *obj)
> @@ -3513,7 +3532,7 @@ static void mtree_print_flatview(gpointer key, gpointer value,
>           return;
>       }
>   
> -    width = MR_ADDR_WIDTH;
> +    width = mr_addr_fmt_width(view->root);
>       while (n--) {
>           const MemoryRegion *mr = range->mr;
>   
> @@ -3643,7 +3662,7 @@ static void mtree_print_as(gpointer key, gpointer value, gpointer user_data)
>       MemoryRegion *mr = key;
>       GSList *as_same_root_mr_list = value;
>       struct AddressSpaceInfo *asi = user_data;
> -    const unsigned int width = MR_ADDR_WIDTH;
> +    const unsigned int width = mr_addr_fmt_width(mr);
>   
>       g_slist_foreach(as_same_root_mr_list, mtree_print_as_name, NULL);
>       mtree_print_mr(mr, 1, width, -mr->addr, false,
> @@ -3692,7 +3711,7 @@ static void mtree_info_as(bool dispatch_tree, bool owner, bool disabled)
>       /* print aliased regions */
>       QTAILQ_FOREACH(ml, &ml_head, mrqueue) {
>           const MemoryRegion *mr = ml->mr;
> -        const unsigned int width = MR_ADDR_WIDTH;
> +        const unsigned int width = mr_addr_fmt_width(mr);
>   
>           qemu_printf("memory-region: %s\n", memory_region_name(mr));
>           mtree_print_mr(mr, 1, width, 0, false, &ml_head, owner, disabled);

That is so neat!
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>