From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0B9D7C624DE for ; Thu, 3 Sep 2026 20:45:11 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x2EIs-0006GF-V3; Thu, 03 Sep 2026 16:44:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x2EIr-0006G5-2T for qemu-devel@nongnu.org; Thu, 03 Sep 2026 16:44:57 -0400 Received: from mx.treblig.org ([2a00:1098:5b::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x2EIm-0001BH-Db for qemu-devel@nongnu.org; Thu, 03 Sep 2026 16:44:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=treblig.org ; s=bytemarkmx; h=Content-Type:MIME-Version:Message-ID:Subject:From:Date:From :Subject; bh=ecwz7jTcTePn8UqTn8t5X8OcxR6zE6hpwrN70HUPRSk=; b=USgVYUxkim6Idysd AApOlTLJ844jy2sUvig2RZQ6V+Vil3lvFNVbGamxH3Pp2dBqEhpWNB6vOH9CfpRxDK2JV6P7ILlR0 4a35b4IoSfKj2NuSo9Br927jkoW0/RlDHR4AUIuptzoQOm7sXxDsLaxxME/edJOny9ckRo7K1ipsm cWztaHESTiMVuWM53Ycjuvw/90UOUpx5f1rJYsT0weWV/qn99vRXZCXuIgwDJh0hn/YBj/RrUbvID 7LNg25IDBdiZsxmJTEBw6FpWIAPjGBwPGhO0S+6KoGu7yEPjuVriW0dJe+nBhrusoTd9gXZeq/fbh pSY0NBrgwybFQKsZwQ==; Received: from dg by mx.treblig.org with local (Exim 4.98.2) (envelope-from ) id 1x2EIh-00000001f1Q-1MHX; Thu, 03 Sep 2026 20:44:47 +0000 Date: Thu, 3 Sep 2026 20:44:47 +0000 From: "Dr. David Alan Gilbert" To: =?iso-8859-1?Q?Marc-Andr=E9?= Lureau , armbru@redhat.com Cc: AlanoSong@163.com, qemu-devel@nongnu.org, laurent@vivier.eu, zhao1.liu@intel.com, atar4qemu@gmail.com Subject: Re: [PATCH v3] monitor: Refine 'info tlb' command Message-ID: References: <20260818132519.186010-1-AlanoSong@163.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-Chocolate: 70 percent or better cocoa solids preferably X-Operating-System: Linux/6.12.107+deb13-amd64 (x86_64) X-Uptime: 20:43:03 up 4 days, 22:04, 3 users, load average: 0.17, 0.08, 0.02 User-Agent: Mutt/2.2.13 (2024-03-09) Received-SPF: pass client-ip=2a00:1098:5b::1; envelope-from=dg@treblig.org; helo=mx.treblig.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Hi Markus, * Dr. David Alan Gilbert (dave@treblig.org) wrote: > * Marc-André Lureau (marcandre.lureau@gmail.com) wrote: > > Hi > > > > On Tue, Aug 18, 2026 at 5:30 PM wrote: > > > > > > When booting an i386 target, the 'info tlb' command > > > may walk the entire page table hierarchy and emit > > > an enormous amount of output. It will take dozens of > > > minutes to print all the info, and > > > The same situation also occurred on sparc32 and > > > m68k targets. > > > > > > So this change do the following: > > > 1) Add a address range argument to help user control > > > the number of output items. > > > 2) Add warning note in help message that such address > > > range argument only supported on target i386, > > > sparc32 and m68k. > > > 3) Print ignore warning when user add such address > > > range argument on other targets (sh4, sparc64, > > > ppc and xtensa). Those targets only print limited > > > tlb info. > > > > > > Signed-off-by: Alano Song > > > > lgtm overall > > > > - m68k print_address_zone() used to be called with page-aligned zones, > > but now it is clipped to arbitrary user ranges, which may not be > > aligned. 1 byte range will be reported as 0kb. We may want to handle > > the case for small ranges. Btw that code could use the macros KiB for > > readability > > > > - A later patch could prune non-overlapping ranges during traversal, > > not just during printing > > Yeh I'd say it's OK, two thoughts: > a) I'd have split the patch into a series with more managable chunks > b) There's quite a bit of repetition which feels like a common helper > might have removed. > > But: > > Reviewed-by: Dr. David Alan Gilbert Can you pick this one up please? Dave > Dave > > > > --- > > > hmp-commands-info.hx | 17 ++++++-- > > > target/i386/monitor.c | 92 ++++++++++++++++++++++++++++----------- > > > target/m68k/cpu.h | 2 +- > > > target/m68k/helper.c | 55 +++++++++++++++-------- > > > target/m68k/monitor.c | 15 ++++++- > > > target/ppc/monitor.c | 6 +++ > > > target/sh4/monitor.c | 5 +++ > > > target/sparc/cpu.h | 3 ++ > > > target/sparc/mmu_helper.c | 40 +++++++++++++---- > > > target/sparc/monitor.c | 23 ++++++++++ > > > target/xtensa/monitor.c | 6 +++ > > > 11 files changed, 206 insertions(+), 58 deletions(-) > > > > > > diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx > > > index 82134eb6c2..f907edf273 100644 > > > --- a/hmp-commands-info.hx > > > +++ b/hmp-commands-info.hx > > > @@ -188,17 +188,26 @@ ERST > > > > > > { > > > .name = "tlb", > > > - .args_type = "", > > > - .params = "", > > > - .help = "show virtual to physical memory mappings", > > > + .args_type = "start:l?,end:l?", > > > + .params = "[start [end]]", > > > + .help = "show virtual to physical memory mappings. " > > > + "output can be extremely large for i386, sparc32 " > > > + "and m68k targets. use 'info tlb [start [end]]' " > > > + "to show a range of entries. Note that the range " > > > + "argument is only supported on i386, sparc32 and " > > > + "m68k targets.", > > > .cmd = hmp_info_tlb, > > > .arch_bitmask = QEMU_ARCH_I386 | QEMU_ARCH_SH4 | QEMU_ARCH_SPARC \ > > > | QEMU_ARCH_PPC | QEMU_ARCH_XTENSA | QEMU_ARCH_M68K, > > > }, > > > > > > SRST > > > - ``info tlb`` > > > + ``info tlb`` [*start* [*end*]] > > > Show virtual to physical memory mappings. > > > + The output can be extremely large for i386, sparc32 and m68k targets. > > > + Use *start* and *end* to print entries located in virtual address > > > + range [start, end] (end is optional). Note that the range argument is > > > + only supported on i386, sparc32 and m68k targets. > > > ERST > > > > > > { > > > diff --git a/target/i386/monitor.c b/target/i386/monitor.c > > > index a536712c75..8db9ab0576 100644 > > > --- a/target/i386/monitor.c > > > +++ b/target/i386/monitor.c > > > @@ -48,11 +48,9 @@ static hwaddr addr_canonical(CPUArchState *env, hwaddr addr) > > > return addr; > > > } > > > > > > -static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr, > > > - hwaddr pte, hwaddr mask) > > > +static void do_print_pte(Monitor *mon, hwaddr addr, > > > + hwaddr pte, hwaddr mask) > > > { > > > - addr = addr_canonical(env, addr); > > > - > > > monitor_printf(mon, HWADDR_FMT_plx ": " HWADDR_FMT_plx > > > " %c%c%c%c%c%c%c%c%c\n", > > > addr, > > > @@ -68,7 +66,25 @@ static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr, > > > pte & PG_RW_MASK ? 'W' : '-'); > > > } > > > > > > -static void tlb_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > +static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr, > > > + hwaddr pte, hwaddr mask, hwaddr size, > > > + hwaddr start, hwaddr end) > > > +{ > > > + hwaddr addr_start = addr_canonical(env, addr); > > > + hwaddr addr_end = addr_canonical(env, addr + size - 1); > > > + /* > > > + * Print current page [addr_start, addr_end] only if it overlaps the > > > + * requested virtual address range [start, end]. > > > + */ > > > + if (addr_start > end || addr_end < start) { > > > + return; > > > + } > > > + > > > + do_print_pte(mon, addr_start, pte, mask); > > > +} > > > + > > > +static void tlb_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > + hwaddr start, hwaddr end) > > > { > > > const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; > > > unsigned int l1, l2; > > > @@ -80,15 +96,16 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > if (pde & PG_PRESENT_MASK) { > > > if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { > > > /* 4M pages */ > > > - print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1)); > > > + print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1), > > > + 0x400000, start, end); > > > } else { > > > for(l2 = 0; l2 < 1024; l2++) { > > > pte = address_space_ldl_le(as, (pde & ~0xfff) + l2 * 4, > > > attrs, NULL); > > > if (pte & PG_PRESENT_MASK) { > > > print_pte(mon, env, (l1 << 22) + (l2 << 12), > > > - pte & ~PG_PSE_MASK, > > > - ~0xfff); > > > + pte & ~PG_PSE_MASK, ~0xfff, 0x1000, > > > + start, end); > > > } > > > } > > > } > > > @@ -96,7 +113,8 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > } > > > } > > > > > > -static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > +static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > + hwaddr start, hwaddr end) > > > { > > > const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; > > > unsigned int l1, l2, l3; > > > @@ -114,17 +132,19 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > if (pde & PG_PSE_MASK) { > > > /* 2M pages with PAE, CR4.PSE is ignored */ > > > print_pte(mon, env, (l1 << 30) + (l2 << 21), pde, > > > - ~((hwaddr)(1 << 20) - 1)); > > > + ~((hwaddr)(1 << 20) - 1), 0x200000, > > > + start, end); > > > } else { > > > pt_addr = pde & 0x3fffffffff000ULL; > > > for (l3 = 0; l3 < 512; l3++) { > > > pte = address_space_ldq_le(as, pt_addr + l3 * 8, > > > attrs, NULL); > > > if (pte & PG_PRESENT_MASK) { > > > - print_pte(mon, env, (l1 << 30) + (l2 << 21) > > > - + (l3 << 12), > > > + print_pte(mon, env, > > > + (l1 << 30) + (l2 << 21) + (l3 << 12), > > > pte & ~PG_PSE_MASK, > > > - ~(hwaddr)0xfff); > > > + ~(hwaddr)0xfff, 0x1000, > > > + start, end); > > > } > > > } > > > } > > > @@ -136,7 +156,8 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > > > > #ifdef TARGET_X86_64 > > > static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > - uint64_t l0, uint64_t pml4_addr) > > > + uint64_t l0, uint64_t pml4_addr, hwaddr start, > > > + hwaddr end) > > > { > > > const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; > > > uint64_t l1, l2, l3, l4; > > > @@ -159,7 +180,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > if (pdpe & PG_PSE_MASK) { > > > /* 1G pages, CR4.PSE is ignored */ > > > print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30), > > > - pdpe, 0x3ffffc0000000ULL); > > > + pdpe, 0x3ffffc0000000ULL, 0x40000000, start, end); > > > continue; > > > } > > > > > > @@ -172,8 +193,9 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > > > > if (pde & PG_PSE_MASK) { > > > /* 2M pages, CR4.PSE is ignored */ > > > - print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30) + > > > - (l3 << 21), pde, 0x3ffffffe00000ULL); > > > + print_pte(mon, env, > > > + (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21), > > > + pde, 0x3ffffffe00000ULL, 0x200000, start, end); > > > continue; > > > } > > > > > > @@ -182,9 +204,11 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > pte = address_space_ldq_le(as, pt_addr + l4 * 8, > > > attrs, NULL); > > > if (pte & PG_PRESENT_MASK) { > > > - print_pte(mon, env, (l0 << 48) + (l1 << 39) + > > > - (l2 << 30) + (l3 << 21) + (l4 << 12), > > > - pte & ~PG_PSE_MASK, 0x3fffffffff000ULL); > > > + print_pte(mon, env, > > > + (l0 << 48) + (l1 << 39) + (l2 << 30) + > > > + (l3 << 21) + (l4 << 12), > > > + pte & ~PG_PSE_MASK, > > > + 0x3fffffffff000ULL, 0x1000, start, end); > > > } > > > } > > > } > > > @@ -192,7 +216,8 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > } > > > } > > > > > > -static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > +static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as, > > > + hwaddr start, hwaddr end) > > > { > > > const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; > > > uint64_t l0; > > > @@ -203,7 +228,8 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as) > > > for (l0 = 0; l0 < 512; l0++) { > > > pml5e = address_space_ldq_le(as, pml5_addr + l0 * 8, attrs, NULL); > > > if (pml5e & PG_PRESENT_MASK) { > > > - tlb_info_la48(mon, env, as, l0, pml5e & 0x3fffffffff000ULL); > > > + tlb_info_la48(mon, env, as, l0, pml5e & 0x3fffffffff000ULL, > > > + start, end); > > > } > > > } > > > } > > > @@ -213,6 +239,18 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > { > > > CPUArchState *env; > > > AddressSpace *as; > > > + hwaddr start = 0, end = HWADDR_MAX; > > > + > > > + if (qdict_haskey(qdict, "start")) { > > > + start = (hwaddr)qdict_get_int(qdict, "start"); > > > + } > > > + if (qdict_haskey(qdict, "end")) { > > > + end = (hwaddr)qdict_get_int(qdict, "end"); > > > + } > > > + if (start > end) { > > > + monitor_printf(mon, "Invalid address range: start > end.\n"); > > > + return; > > > + } > > > > > > env = mon_get_cpu_env(mon); > > > if (!env) { > > > @@ -229,17 +267,19 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > #ifdef TARGET_X86_64 > > > if (env->hflags & HF_LMA_MASK) { > > > if (env->cr[4] & CR4_LA57_MASK) { > > > - tlb_info_la57(mon, env, as); > > > + tlb_info_la57(mon, env, as, start, end); > > > } else { > > > - tlb_info_la48(mon, env, as, 0, env->cr[3] & 0x3fffffffff000ULL); > > > + tlb_info_la48(mon, env, as, 0, > > > + env->cr[3] & 0x3fffffffff000ULL, > > > + start, end); > > > } > > > } else > > > #endif > > > { > > > - tlb_info_pae32(mon, env, as); > > > + tlb_info_pae32(mon, env, as, start, end); > > > } > > > } else { > > > - tlb_info_32(mon, env, as); > > > + tlb_info_32(mon, env, as, start, end); > > > } > > > } > > > > > > diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h > > > index 7cf3791108..b129cb150f 100644 > > > --- a/target/m68k/cpu.h > > > +++ b/target/m68k/cpu.h > > > @@ -606,6 +606,6 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, > > > #define TB_FLAGS_TRACE 16 > > > #define TB_FLAGS_TRACE_BIT (1 << TB_FLAGS_TRACE) > > > > > > -void dump_mmu(CPUM68KState *env); > > > +void dump_mmu(CPUM68KState *env, hwaddr start, hwaddr end); > > > > > > #endif > > > diff --git a/target/m68k/helper.c b/target/m68k/helper.c > > > index 5f91d206f5..1b854c912b 100644 > > > --- a/target/m68k/helper.c > > > +++ b/target/m68k/helper.c > > > @@ -461,27 +461,46 @@ void m68k_switch_sp(CPUM68KState *env) > > > /* MMU: 68040 only */ > > > > > > static void print_address_zone(uint32_t logical, uint32_t physical, > > > - uint32_t size, int attr) > > > + uint32_t size, int attr, > > > + hwaddr start, hwaddr end) > > > { > > > + uint64_t zone_start = logical; > > > + uint64_t zone_end = zone_start + size - 1; > > > + uint64_t zone_len; > > > + > > > + /* > > > + * Print current zone [zone_start, zone_end] only if it overlaps the > > > + * requested virtual address range [start, end]. > > > + */ > > > + if (zone_end < start || zone_start > end) { > > > + return; > > > + } > > > + > > > + physical += (uint32_t)(start > zone_start ? start - zone_start : 0); > > > + zone_start = zone_start > start ? zone_start : start; > > > + zone_end = zone_end < end ? zone_end : end; > > > + zone_len = zone_end - zone_start + 1; > > > + > > > qemu_printf("%08x - %08x -> %08x - %08x %c ", > > > - logical, logical + size - 1, > > > - physical, physical + size - 1, > > > + (uint32_t)zone_start, (uint32_t)zone_end, > > > + physical, physical + (uint32_t)(zone_len - 1), > > > attr & 4 ? 'W' : '-'); > > > - size >>= 10; > > > - if (size < 1024) { > > > - qemu_printf("(%d KiB)\n", size); > > > + zone_len >>= 10; > > > + if (zone_len < 1024) { > > > + qemu_printf("(%d KiB)\n", (int)zone_len); > > > } else { > > > - size >>= 10; > > > - if (size < 1024) { > > > - qemu_printf("(%d MiB)\n", size); > > > + zone_len >>= 10; > > > + if (zone_len < 1024) { > > > + qemu_printf("(%d MiB)\n", (int)zone_len); > > > } else { > > > - size >>= 10; > > > - qemu_printf("(%d GiB)\n", size); > > > + zone_len >>= 10; > > > + qemu_printf("(%d GiB)\n", (int)zone_len); > > > } > > > } > > > } > > > > > > -static void dump_address_map(CPUM68KState *env, uint32_t root_pointer) > > > +static void dump_address_map(CPUM68KState *env, uint32_t root_pointer, > > > + hwaddr start, hwaddr end) > > > { > > > int tic_size, tic_shift; > > > uint32_t tib_mask; > > > @@ -550,7 +569,8 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer) > > > size = last_logical + (1 << tic_shift) - > > > first_logical; > > > print_address_zone(first_logical, > > > - first_physical, size, last_attr); > > > + first_physical, size, last_attr, > > > + start, end); > > > } > > > first_logical = logical; > > > first_physical = physical; > > > @@ -560,7 +580,8 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer) > > > } > > > if (first_logical != logical || (attr & 4) != (last_attr & 4)) { > > > size = logical + (1 << tic_shift) - first_logical; > > > - print_address_zone(first_logical, first_physical, size, last_attr); > > > + print_address_zone(first_logical, first_physical, size, last_attr, > > > + start, end); > > > } > > > } > > > > > > @@ -610,7 +631,7 @@ static void dump_ttr(uint32_t ttr) > > > M68K_DESC_USERATTR_SHIFT); > > > } > > > > > > -void dump_mmu(CPUM68KState *env) > > > +void dump_mmu(CPUM68KState *env, hwaddr start, hwaddr end) > > > { > > > if ((env->mmu.tcr & M68K_TCR_ENABLED) == 0) { > > > qemu_printf("Translation disabled\n"); > > > @@ -675,10 +696,10 @@ void dump_mmu(CPUM68KState *env) > > > dump_ttr(env->mmu.ttr[M68K_DTTR1]); > > > > > > qemu_printf("SRP: 0x%08x\n", env->mmu.srp); > > > - dump_address_map(env, env->mmu.srp); > > > + dump_address_map(env, env->mmu.srp, start, end); > > > > > > qemu_printf("URP: 0x%08x\n", env->mmu.urp); > > > - dump_address_map(env, env->mmu.urp); > > > + dump_address_map(env, env->mmu.urp, start, end); > > > } > > > > > > static int check_TTR(uint32_t ttr, int *prot, target_ulong addr, > > > diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c > > > index 3e0df40a6b..bcb528d8e3 100644 > > > --- a/target/m68k/monitor.c > > > +++ b/target/m68k/monitor.c > > > @@ -9,15 +9,28 @@ > > > #include "cpu.h" > > > #include "monitor/hmp.h" > > > #include "monitor/monitor.h" > > > +#include "qobject/qdict.h" > > > > > > void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > { > > > CPUArchState *env1 = mon_get_cpu_env(mon); > > > + hwaddr start = 0, end = HWADDR_MAX; > > > > > > if (!env1) { > > > monitor_printf(mon, "No CPU available\n"); > > > return; > > > } > > > > > > - dump_mmu(env1); > > > + if (qdict_haskey(qdict, "start")) { > > > + start = (hwaddr)qdict_get_int(qdict, "start"); > > > + } > > > + if (qdict_haskey(qdict, "end")) { > > > + end = (hwaddr)qdict_get_int(qdict, "end"); > > > + } > > > + if (start > end) { > > > + monitor_printf(mon, "Invalid address range: start > end.\n"); > > > + return; > > > + } > > > + > > > + dump_mmu(env1, start, end); > > > } > > > diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c > > > index 7c88e0e2bd..753ed6b93d 100644 > > > --- a/target/ppc/monitor.c > > > +++ b/target/ppc/monitor.c > > > @@ -10,6 +10,7 @@ > > > #include "monitor/monitor.h" > > > #include "monitor/hmp.h" > > > #include "cpu.h" > > > +#include "qobject/qdict.h" > > > > > > void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > { > > > @@ -19,5 +20,10 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > monitor_printf(mon, "No CPU available\n"); > > > return; > > > } > > > + > > > + if (qdict_haskey(qdict, "start") || qdict_haskey(qdict, "end")) { > > > + monitor_printf(mon, "The range arguments will be ignored.\n"); > > > + } > > > + > > > dump_mmu(env1); > > > } > > > diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c > > > index 50324d3600..c804824bab 100644 > > > --- a/target/sh4/monitor.c > > > +++ b/target/sh4/monitor.c > > > @@ -25,6 +25,7 @@ > > > #include "cpu.h" > > > #include "monitor/monitor.h" > > > #include "monitor/hmp.h" > > > +#include "qobject/qdict.h" > > > > > > static void print_tlb(Monitor *mon, int idx, tlb_t *tlb) > > > { > > > @@ -48,6 +49,10 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > return; > > > } > > > > > > + if (qdict_haskey(qdict, "start") || qdict_haskey(qdict, "end")) { > > > + monitor_printf(mon, "The range arguments will be ignored.\n"); > > > + } > > > + > > > monitor_printf (mon, "ITLB:\n"); > > > for (i = 0 ; i < ITLB_SIZE ; i++) > > > print_tlb (mon, i, &env->itlb[i]); > > > diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h > > > index 5f583ed9de..11f94b6bd8 100644 > > > --- a/target/sparc/cpu.h > > > +++ b/target/sparc/cpu.h > > > @@ -601,6 +601,9 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, > > > bool probe, uintptr_t retaddr); > > > target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); > > > void dump_mmu(CPUSPARCState *env); > > > +#ifndef TARGET_SPARC64 > > > +void dump_mmu_range(CPUSPARCState *env, hwaddr start, hwaddr end); > > > +#endif > > > > > > #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) > > > int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr, > > > diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c > > > index 07ba25dfce..65a30b438b 100644 > > > --- a/target/sparc/mmu_helper.c > > > +++ b/target/sparc/mmu_helper.c > > > @@ -354,7 +354,32 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev) > > > return 0; > > > } > > > > > > +static void print_tlb_entry(target_ulong va, hwaddr pa, uint32_t pde, > > > + const char *indent, const char *kind, > > > + hwaddr size, hwaddr start, hwaddr end) > > > +{ > > > + hwaddr va_hw_start = (hwaddr)va; > > > + hwaddr va_hw_end = (hwaddr)(va + size - 1); > > > + > > > + /* > > > + * Print current region [va_hw_start, va_hw_end] only if it overlaps the > > > + * requested virtual address range [start, end]. > > > + */ > > > + if (va_hw_start > end || va_hw_end < start) { > > > + return; > > > + } > > > + > > > + qemu_printf("%sVA: " TARGET_FMT_lx ", PA: " HWADDR_FMT_plx > > > + " %s: " TARGET_FMT_lx "\n", > > > + indent, va, pa, kind, pde); > > > +} > > > + > > > void dump_mmu(CPUSPARCState *env) > > > +{ > > > + dump_mmu_range(env, 0, HWADDR_MAX); > > > +} > > > + > > > +void dump_mmu_range(CPUSPARCState *env, hwaddr start, hwaddr end) > > > { > > > CPUState *cs = env_cpu(env); > > > target_ulong va, va1, va2; > > > @@ -373,8 +398,8 @@ void dump_mmu(CPUSPARCState *env) > > > } else { > > > pa = tres.physaddr; > > > } > > > - qemu_printf("VA: " TARGET_FMT_lx ", PA: " HWADDR_FMT_plx > > > - " PDE: " TARGET_FMT_lx "\n", va, pa, pde); > > > + print_tlb_entry(va, pa, pde, "", "PDE", 16 * 1024 * 1024, > > > + start, end); > > > for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { > > > pde = mmu_probe(env, va1, 1); > > > if (pde) { > > > @@ -383,9 +408,8 @@ void dump_mmu(CPUSPARCState *env) > > > } else { > > > pa = tres.physaddr; > > > } > > > - qemu_printf(" VA: " TARGET_FMT_lx ", PA: " > > > - HWADDR_FMT_plx " PDE: " TARGET_FMT_lx "\n", > > > - va1, pa, pde); > > > + print_tlb_entry(va1, pa, pde, " ", "PDE", 256 * 1024, > > > + start, end); > > > for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { > > > pde = mmu_probe(env, va2, 0); > > > if (pde) { > > > @@ -394,10 +418,8 @@ void dump_mmu(CPUSPARCState *env) > > > } else { > > > pa = tres.physaddr; > > > } > > > - qemu_printf(" VA: " TARGET_FMT_lx ", PA: " > > > - HWADDR_FMT_plx " PTE: " > > > - TARGET_FMT_lx "\n", > > > - va2, pa, pde); > > > + print_tlb_entry(va2, pa, pde, " ", "PTE", > > > + 4 * 1024, start, end); > > > } > > > } > > > } > > > diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c > > > index 36f3d8d58e..993e411a37 100644 > > > --- a/target/sparc/monitor.c > > > +++ b/target/sparc/monitor.c > > > @@ -25,6 +25,7 @@ > > > #include "cpu.h" > > > #include "monitor/monitor.h" > > > #include "monitor/hmp.h" > > > +#include "qobject/qdict.h" > > > > > > > > > void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > @@ -35,5 +36,27 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > monitor_printf(mon, "No CPU available\n"); > > > return; > > > } > > > + > > > +#ifdef TARGET_SPARC64 > > > + if (qdict_haskey(qdict, "start") || qdict_haskey(qdict, "end")) { > > > + monitor_printf(mon, "The range arguments will be ignored.\n"); > > > + } > > > + > > > dump_mmu(env1); > > > +#else > > > + hwaddr start = 0, end = HWADDR_MAX; > > > + > > > + if (qdict_haskey(qdict, "start")) { > > > + start = (hwaddr)qdict_get_int(qdict, "start"); > > > + } > > > + if (qdict_haskey(qdict, "end")) { > > > + end = (hwaddr)qdict_get_int(qdict, "end"); > > > + } > > > + if (start > end) { > > > + monitor_printf(mon, "Invalid address range: start > end.\n"); > > > + return; > > > + } > > > + > > > + dump_mmu_range(env1, start, end); > > > +#endif > > > } > > > diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c > > > index 2af84934f8..df572cba42 100644 > > > --- a/target/xtensa/monitor.c > > > +++ b/target/xtensa/monitor.c > > > @@ -25,6 +25,7 @@ > > > #include "cpu.h" > > > #include "monitor/monitor.h" > > > #include "monitor/hmp.h" > > > +#include "qobject/qdict.h" > > > > > > void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > { > > > @@ -34,5 +35,10 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict) > > > monitor_printf(mon, "No CPU available\n"); > > > return; > > > } > > > + > > > + if (qdict_haskey(qdict, "start") || qdict_haskey(qdict, "end")) { > > > + monitor_printf(mon, "The range arguments will be ignored.\n"); > > > + } > > > + > > > dump_mmu(env1); > > > } > > > -- > > > 2.43.0 > > > > > > > > > > > > -- > > Marc-André Lureau > -- > -----Open up your eyes, open up your mind, open up your code ------- > / Dr. David Alan Gilbert | Running GNU/Linux | Happy \ > \ dave @ treblig.org | | In Hex / > \ _________________________|_____ http://www.treblig.org |_______/ > -- -----Open up your eyes, open up your mind, open up your code ------- / Dr. David Alan Gilbert | Running GNU/Linux | Happy \ \ dave @ treblig.org | | In Hex / \ _________________________|_____ http://www.treblig.org |_______/