* Alano Song ([email protected]) wrote:

See below:

> At 2026-07-02 05:05:58, "Dr. David Alan Gilbert" <[email protected]> wrote:
> >(Added Phil's new address in)
> >
> >* [email protected] ([email protected]) 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,
> >> because each monitor print function will holds 'mon_lock'.
> >> This effectively hangs the qemu monitor.
> >> 
> >> It may be better to add warning note in help message,
> >> and add a address range by argument to help user control
> >> the number of output items.
> >> 
> >> Signed-off-by: Alano Song <[email protected]>
> >> ---
> >>  hmp-commands-info.hx  | 12 ++++---
> >>  target/i386/monitor.c | 82 +++++++++++++++++++++++++++++--------------
> >>  2 files changed, 64 insertions(+), 30 deletions(-)
> >> 
> >> diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
> >> index 82134eb6c2..3189e20de3 100644
> >> --- a/hmp-commands-info.hx
> >> +++ b/hmp-commands-info.hx
> >> @@ -188,17 +188,21 @@ 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 target. "
> >> +                      "use 'info tlb [start] [end]' to show a range of 
> >> entries.",
> >
> >That can be;
> >> +                      "The address range can be limited with the optional 
> >> parameters."
> >
> >Now, is that the *virtual* address - because it feels like that needs 
> >specifying.
> >
> >>          .cmd        = hmp_info_tlb,
> >>          .arch_bitmask = QEMU_ARCH_I386 | QEMU_ARCH_SH4 | QEMU_ARCH_SPARC \
> >>                          | QEMU_ARCH_PPC | QEMU_ARCH_XTENSA | 
> >> QEMU_ARCH_M68K,
> >
> >You have added the start/end params to the help, but only implemented it on 
> >x86.
> >That seems odd.
> >
> >Dave
> 
> >
> 
> 
> Hi Dr. Gilbert,
> 
> On this patch, I’m currently enabling the `start`/`end` parameters only for
> x86, since other targets typically maintain a relatively small TLB.
> 
> For example, xtensa only has a handful of entries, as shown below, so it’s
> reasonable to simply ignore start/end parameters and dump all items:

We shouldn't blindly ignore parameters; we should always tell the user,
this is mainly because a user would be very confused if they were using these
parameters and still getting pages of output from say sparc32.

Perhaps if you create a little helper function that the unsupported
hmp_info_tlb's can call to check it.  Something like


  if (hmp_check_unsupported_info_tlb_params(qdict,something)) {
      return;
  }

so then it's easy to add that to the ones that's not supported.

> // target/xtensa/cpu.h
> ...
> #define MAX_TLB_WAY_SIZE 8
> ...
> struct CPUArchState {
> ...
> #ifndef CONFIG_USER_ONLY
>     xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE];
>     xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE];
> ...
> 
> The same applies to sparc64, ppc, and sh4.
> 
> 
> Thanks for the reminder.
> I went through all architectures supporting the
> 
> `info tlb` command. I noticed that sparc32 and m68k may also produce a
> large number of TLB entries, so I plan to extend start/end filtering
> to those as well.
> What do you think?
> 
Yeh that would be great, I think the more important bit is not to confuse
users about ones which aren't supported.

> >>  SRST
> >> -  ``info tlb``
> >> +  ``info tlb`` [*start* [*end*]]
> >>      Show virtual to physical memory mappings.
> >> +    The output can be extremely large for i386 target.
> >> +    Use *start* and *end* to print entries located in address range 
> >> [start, end].
> >>  ERST

I think I'd change it to something like 
  *start* and *end can restrict the address range printed to [start, end]
  (This restriction is only supported on i386)

Dave

> Alano.
> 
> 
> >>      },
> >>  
> >>  SRST
> >> -  ``info tlb``
> >> +  ``info tlb`` [*start* [*end*]]
> >>      Show virtual to physical memory mappings.
> >> +    The output can be extremely large for i386 target.
> >> +    Use *start* and *end* to print entries located in address range 
> >> [start, end].
> >>  ERST
> >>  
> >>      {
> >> diff --git a/target/i386/monitor.c b/target/i386/monitor.c
> >> index a536712c75..c0e0c3e405 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, CPUArchState *env, 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,20 @@ 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 start, hwaddr end)
> >> +{
> >> +    addr = addr_canonical(env, addr);
> >> +    if (addr < start || addr > end) {
> >> +        return;
> >> +    }
> >> +
> >> +    do_print_pte(mon, env, addr, 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 +91,15 @@ 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),
> >> +                          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, start, end);
> >>                      }
> >>                  }
> >>              }
> >> @@ -96,7 +107,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 +126,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),
> >> +                                  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,
> >> +                                          start, end);
> >>                              }
> >>                          }
> >>                      }
> >> @@ -136,7 +150,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 +174,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, start, end);
> >>                  continue;
> >>              }
> >>  
> >> @@ -172,8 +187,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, start, end);
> >>                      continue;
> >>                  }
> >>  
> >> @@ -182,9 +198,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, start, end);
> >>                      }
> >>                  }
> >>              }
> >> @@ -192,7 +210,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 +222,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 +233,14 @@ 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");
> >> +    }
> >>  
> >>      env = mon_get_cpu_env(mon);
> >>      if (!env) {
> >> @@ -229,17 +257,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);
> >>      }
> >>  }
> >>  
> >> -- 
> >> 2.43.0
> >> 
> >-- 
> > -----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   |_______/

Reply via email to