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
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);
>
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
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>
© 2016 - 2026 Red Hat, Inc.