tile kgdb: fix bug in copy to gdb regs, and optimize memset
authorChris Metcalf <cmetcalf@ezchip.com>
Mon, 25 Jan 2016 20:05:34 +0000 (15:05 -0500)
committerChris Metcalf <cmetcalf@ezchip.com>
Wed, 2 Mar 2016 20:19:44 +0000 (15:19 -0500)
David Binderman pointed out that we were doing a full memset()
of the gdb register buffer and then doing a memcpy() to it that
was almost as big.  This commit optimizes that by only doing a
memset() of the registers that are intended to be zero.

While making this change I noticed that we were not copying the
link register (LR, number 55) due to a fencepost error in commit
f419e6f63c5a ("arch: tile: kernel: kgdb.c: Use memcpy() instead of
pointer copy one by one"), and I've corrected that as well.

Reported-by: David Binderman <dcb314@hotmail.com>
Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
arch/tile/kernel/kgdb.c

index a506c2c..6ad9992 100644 (file)
@@ -126,15 +126,15 @@ void
 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
 {
        struct pt_regs *thread_regs;
 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
 {
        struct pt_regs *thread_regs;
+       const int NGPRS = TREG_LAST_GPR + 1;
 
        if (task == NULL)
                return;
 
 
        if (task == NULL)
                return;
 
-       /* Initialize to zero. */
-       memset(gdb_regs, 0, NUMREGBYTES);
-
        thread_regs = task_pt_regs(task);
        thread_regs = task_pt_regs(task);
-       memcpy(gdb_regs, thread_regs, TREG_LAST_GPR * sizeof(unsigned long));
+       memcpy(gdb_regs, thread_regs, NGPRS * sizeof(unsigned long));
+       memset(&gdb_regs[NGPRS], 0,
+              (TILEGX_PC_REGNUM - NGPRS) * sizeof(unsigned long));
        gdb_regs[TILEGX_PC_REGNUM] = thread_regs->pc;
        gdb_regs[TILEGX_FAULTNUM_REGNUM] = thread_regs->faultnum;
 }
        gdb_regs[TILEGX_PC_REGNUM] = thread_regs->pc;
        gdb_regs[TILEGX_FAULTNUM_REGNUM] = thread_regs->faultnum;
 }