All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Howard <cvz185@web.de>
To: Peter Maydell <peter.maydell@linaro.org>, qemu-devel@nongnu.org
Subject: Re: Possible bug in Aarch64 single-stepping [PATCH]
Date: Sun, 8 May 2022 21:27:27 +0200	[thread overview]
Message-ID: <C07CCAE4-1679-4D7C-A472-57B9939D5DE0@web.de> (raw)
In-Reply-To: <CAFEAcA-Dy=nY9SCtxv0omYCQqDqGq6Qwvja4c6f_9rPR8L-KCA@mail.gmail.com>

On 8. May 2022, at 14:18, Peter Maydell <peter.maydell@linaro.org> wrote:

> On Sat, 7 May 2022 at 15:18, Chris Howard <cvz185@web.de> wrote:
>> PS. In plain gdb (ie. no nice user interface) a large number (but not all) of the system registers gets displayed after each step. It would be nice if these were sorted in some way. At the moment they’re completely jumbled — not alphabetic, not grouped by EL, nor by “meaning”  (DBGWVR0_EL1 isn’t necessarily next to DBGWCR0_EL1).
>> 
>> Also, there are multiple (identical?) instances of “DBGBVR” and “DBGBCR” (and  “DBGWVR” and “DBGWCR”) rather than the expected “DBGWVR0_EL1”, “DBGWVR1_EL1” etc.
>> 
>> Would this be a QEMU or a GDB issue? Or isn’t it an issue at all? :-)
> 
> My gdb doesn't do that. Basically QEMU provides gdb with some XML
> telling it that the sysregs are present, but it's up to gdb at
> what points it chooses to display what registers and how it does that.
> 
> The system register read access via the gdbstub is "best-effort"
> on QEMU's part -- we implement it to the extent that it wasn't too
> difficult to do, but there are some sharp edges, like the
> register names not always being quite right, and also the way
> that if you try to read a register that isn't supposed to be
> accessible by the current EL you might find it's not correct.
> Trying to read SP_EL2 while at EL2 is an example of that.
> 
> The reason register names are sometimes funny is that the
> infrastructure for system registers within QEMU was originally
> written with the assumption that the name strings were merely
> for convenience when debugging QEMU itself, so it's sometimes
> a bit careless about them. We only added the "tell GDB about
> these" part later.
> 
> That said, adding the numbers into the watchpoint and breakpoint
> registers would be pretty easy, so we should do that. That is,
> in this code:
> https://gitlab.com/qemu-project/qemu/-/blob/master/target/arm/helper.c#L6567
> we should use g_strdup_printf() to create unique per-register
> names, the same way we do for the PMU registers already here:
> https://gitlab.com/qemu-project/qemu/-/blob/master/target/arm/helper.c#L6632
> 
> thanks
> -- PMM

Thanks for the explanation. What with this being “pretty easy” I’m attempting my first ever patch!  :-)

BE WARNED!

This is a context diff with respect to the cloned git repository (Version 7.0.50)

$ git clone https://gitlab.com/qemu-project/qemu.git

created with

$ diff -c qemu/target/arm/helper.c qemu-patch/target/arm/helper.c > aarch-dbg-regnames.patch

to be applied (in the target/arm directory) with

$ patch -p3 <../../../aarch-dbg-regnames.patch


— chris


 
*** qemu/target/arm/helper.c	2022-05-08 20:41:48.000000000 +0200
--- qemu-patch/target/arm/helper.c	2022-05-08 20:55:25.000000000 +0200
***************
*** 6551,6559 ****
          define_one_arm_cp_reg(cpu, &dbgdidr);
      }
  
!     /* Note that all these register fields hold "number of Xs minus 1". */
!     brps = arm_num_brps(cpu);
!     wrps = arm_num_wrps(cpu);
      ctx_cmps = arm_num_ctx_cmps(cpu);
  
      assert(ctx_cmps <= brps);
--- 6551,6559 ----
          define_one_arm_cp_reg(cpu, &dbgdidr);
      }
  
!     /* Note that all these reg fields (in ID_AA64DFR0_EL1) hold "number of Xs minus 1". */
!     brps = arm_num_brps(cpu);			/* returns actual number of breakpoints */
!     wrps = arm_num_wrps(cpu);			/* returns actual number of watchpoints */
      ctx_cmps = arm_num_ctx_cmps(cpu);
  
      assert(ctx_cmps <= brps);
***************
*** 6565,6578 ****
      }
  
      for (i = 0; i < brps; i++) {
          ARMCPRegInfo dbgregs[] = {
!             { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
                .writefn = dbgbvr_write, .raw_writefn = raw_write
              },
!             { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
--- 6565,6580 ----
      }
  
      for (i = 0; i < brps; i++) {
+ 		char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i);
+ 		char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i);
          ARMCPRegInfo dbgregs[] = {
!             { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
                .writefn = dbgbvr_write, .raw_writefn = raw_write
              },
!             { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
***************
*** 6580,6596 ****
              },
          };
          define_arm_cp_regs(cpu, dbgregs);
      }
  
      for (i = 0; i < wrps; i++) {
          ARMCPRegInfo dbgregs[] = {
!             { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
                .writefn = dbgwvr_write, .raw_writefn = raw_write
              },
!             { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
--- 6582,6602 ----
              },
          };
          define_arm_cp_regs(cpu, dbgregs);
+         g_free(dbgbvr_el1_name);
+         g_free(dbgbcr_el1_name);
      }
  
      for (i = 0; i < wrps; i++) {
+ 		char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i);
+ 		char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i);
          ARMCPRegInfo dbgregs[] = {
!             { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
                .writefn = dbgwvr_write, .raw_writefn = raw_write
              },
!             { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
***************
*** 6598,6603 ****
--- 6604,6611 ----
              },
          };
          define_arm_cp_regs(cpu, dbgregs);
+         g_free(dbgwvr_el1_name);
+         g_free(dbgwcr_el1_name);
      }
  }
  



  parent reply	other threads:[~2022-05-08 19:28 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-07 13:42 Possible bug in Aarch64 single-stepping Chris Howard
2022-05-07 14:16 ` Chris Howard
2022-05-08 12:18   ` Peter Maydell
2022-05-08 12:19     ` Peter Maydell
2022-05-08 19:27     ` Chris Howard [this message]
2022-05-10  9:59       ` Possible bug in Aarch64 single-stepping [PATCH] Peter Maydell
2022-05-08 12:08 ` Possible bug in Aarch64 single-stepping Peter Maydell
2022-05-08 19:35   ` Chris Howard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=C07CCAE4-1679-4D7C-A472-57B9939D5DE0@web.de \
    --to=cvz185@web.de \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.