bph / bpha not working.
Konstantin Baydarov
kbaidarov at ru.mvista.com
Thu May 8 04:08:32 PDT 2008
Correct.
On Thu, 8 May 2008 17:03:35 +0800
"jidong xiao" <jidong.xiao at gmail.com> wrote:
> On Mon, May 5, 2008 at 6:44 PM, Konstantin Baydarov
> <kbaidarov at ru.mvista.com> wrote:
> > Yes It's known issue.
> > On Mon, 05 May 2008 13:06:11 +0300
> > Avi Nehori <anehori at checkpoint.com> wrote:
> >
> > > Hi,
> > > I'm trying to set a watch point with bpha as follows :
> > > bpha address dataw 4
> > > but the watchpoint is never called when the memory address is
> > > changed. is it a know bug ?
> > > is there a patch ?
> >
> > Here is my previous mail
> > (http://oss.sgi.com/archives/kdb/2007-11/msg00037.html) with patch
> > that fixes bpha problem: Global HW BP don't work: 1) Install global
> > HW BP root at 192.168.2.10:~#
> > root at 192.168.2.10:~# D
> > Entering kdb (current=0xc04433a0, pid 0) on processor 0 due to
> > Keyboard Entry [0]kdb> bpha do_sync
> > Forced Instruction(Register) BP #0 at 0xc0181539 (do_sync)
> > is enabled in dr0 globally
> > [0]kdb> go
> >
> > -bash: D: command not found
> > root at 192.168.2.10:~#
> >
> > 1) Try CPU 0
> > root at 192.168.2.10:~#
> > root at 192.168.2.10:~# taskset -c 0 sync
> > Instruction(Register) breakpoint #0 at 0xc0181539
> > 0xc0181539 do_sync: push %ebx
> >
> > Entering kdb (0xc1b6d030, pid 1319) on processor 0 due to Debug @
> > 0xc0181539 [0]kdb> go
> > root at 192.168.2.10:~#
> > - OK
> >
> > 1) Try CPU 1
> > root at 192.168.2.10:~#
> > root at 192.168.2.10:~# taskset -c 1 sync
> > root at 192.168.2.10:~#
> > - Doesn't work.
> >
> > Signed-off-by: Konstantin Baydarov <kbaidarov at ru.mvista.com>
> > Description:
> > This patch adds support for global hardware breakpoints to KDB on
> > x86 targets. Hardware breakpoints are installed by setting per CPU
> > db registers. So to make a hardware breakpoint global it should be
> > installed in db registers on every CPU in system. So global hw bp
> > can't be handle by kdb_bp_install_global and kdb_bp_remove_global
> > because these functions are called only on "monarch" CPU,
> > kdb_bp_install_local and kdb_bp_remove_local should be used instead
> > because these are called for all CPUs.
> >
> > Main changes:
> > - kdb_hardbreaks[KDB_MAXHARDBPT] - The processor architecture
> > hardware breakpoint registers descriptors is defined for every
> > CPU:
> > static kdbhard_bp_t kdb_hardbreaks[NR_CPUS][KDB_MAXHARDBPT];
> >
> > - "kdb_bp_t" (main breakpint structure) contains hardware
> > breakpoint registers for every CPU:
> > kdbhard_bp_t* bp_hard[NR_CPUS];
> >
> > - global hardware breakpoint installation and removal is handled
> > by kdb_bp_install_local and kdb_bp_remove_local which are
> > executed on every CPU
> >
> > - kdba_allocbp andkdba_freebp are static, now kdba_alloc_hwbp and
> > kdba_free_hwbp are used for allocating/freeing hardware
> > breakpoint registers. If the hardware breakpoint is global then
> > kdba_alloc_hwbp tries to allocate hardware breakpoint registers
> > on every CPU. If there is no free hardware breakpoint on a CPU the
> > allocation fails.
> >
> > - bph_installed was added to the hardware breakpoint descriptor to
> > track per CPU hardware breakpoint installation.
> >
> > Patch against kernel 2.6.24-rc2
> >
> > Index: linux-2.6.24-rc2/arch/x86/kdb/kdba_bp_32.c
> > ===================================================================
> > --- linux-2.6.24-rc2.orig/arch/x86/kdb/kdba_bp_32.c
> > +++ linux-2.6.24-rc2/arch/x86/kdb/kdba_bp_32.c
> > @@ -22,10 +22,10 @@ static char *kdba_rwtypes[] = { "Instruc
> >
> > /*
> > * Table describing processor architecture hardware
> > - * breakpoint registers.
> > + * breakpoint registers for every CPU.
> > */
> >
> > -static kdbhard_bp_t kdb_hardbreaks[KDB_MAXHARDBPT];
> > +static kdbhard_bp_t kdb_hardbreaks[NR_CPUS][KDB_MAXHARDBPT];
> >
> > /*
> > + * kdba_free_hwbp
> > + *
> > + * Frees allocated hw registers descriptors for bp.
> > + * If hw bp is global, hw registers descriptors will be freed
> > + * on every CPU.
> > + *
> > + * Parameters:
> > + * bp - hardware bp
> > + * Outputs:
> > + * None.
> > + * Returns:
> > + * None
> > + * Locking:
> > + * None.
> > + * Remarks:
> > + * Should be called with correct bp->bp_template
> > + */
> > +
> > +void
> > +kdba_free_hwbp(kdb_bp_t *bp)
> > +{
> > + int i;
> > +
> > + /* When kernel enters KDB, first, all local bps
> > + * are removed, so here we don't need to clear
> > + * debug registers.
> > + */
> > +
> > + if (bp->bp_global){
> > + for (i = 0; i < NR_CPUS; ++i) {
> > + if (!cpu_online(i))
> > + continue;
> > + if (bp->bp_hard[i])
> > + kdba_freebp(bp->bp_hard[i]);
> > + bp->bp_hard[i] = 0;
> > + }
> > + } else {
> > + kdba_freebp(bp->bp_hard[bp->bp_cpu]);
> > + bp->bp_hard[bp->bp_cpu] = NULL;
> > + }
> > + bp->bp_hardtype = 0;
> > +}
> > +
> > +/*
> > * kdba_initbp
> > *
> > * Initialize the breakpoint table for the hardware breakpoint
> > @@ -653,7 +749,7 @@ kdba_freebp(kdbhard_bp_t *bph)
> > void
> > kdba_initbp(void)
> > {
> > - int i;
> > + int i,j;
> > kdbhard_bp_t *bph;
> >
> > /*
> > @@ -662,9 +758,15 @@ kdba_initbp(void)
> >
> > memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
> >
> > - for(i=0,bph=kdb_hardbreaks; i<KDB_MAXHARDBPT; i++, bph++) {
> > - bph->bph_reg = i;
> > - bph->bph_free = 1;
> > + for (i = 0; i < NR_CPUS; ++i) {
> > + /* Called early so we don't know actual
> > + * ammount of CPUs
> > + */
> > + for(j=0; j < KDB_MAXHARDBPT; j++) {
> > + bph=&(kdb_hardbreaks[i][j]);
> > + bph->bph_reg = j;
> > + bph->bph_free = 1;
> > + }
> > }
> > }
> >
> > @@ -698,6 +800,8 @@ kdba_initbp(void)
> > int
> > kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
> > {
> > + int cpu = smp_processor_id();
> > +
> > /*
> > * Install the breakpoint, if it is not already installed.
> > */
> > @@ -707,15 +811,27 @@ kdba_installbp(struct pt_regs *regs, kdb
> > }
> > if (!KDB_STATE(SSBPT))
> > bp->bp_delay = 0;
> > - if (!bp->bp_installed) {
> > - if (bp->bp_hardtype) {
> > +
> > + if (bp->bp_hardtype) {
> > + if (KDB_DEBUG(BP) && !bp->bp_global && cpu !=
> > bp->bp_cpu){
> > + kdb_printf("kdba_removebp: cpu !=
> > bp->bp_cpu for local hw bp\n");
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> "s/kdba_removebp/kdba_installbp/", right?
> > + }
> > +
> > + if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){
> > + kdb_printf("kdba_removebp: Error -
> > bp_hard[smp_processor_id()] is emply\n");
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> And here.
> > + return 1;
> > + }
> > +
> > + if (!bp->bp_hard[cpu]->bph_installed){
> > kdba_installdbreg(bp);
> > - bp->bp_installed = 1;
> > + bp->bp_hard[cpu]->bph_installed = 1;
> > if (KDB_DEBUG(BP)) {
> > kdb_printf("kdba_installbp hardware
> > reg %ld at " kdb_bfd_vma_fmt "\n",
> > - bp->bp_hard->bph_reg,
> > bp->bp_addr);
> > + bp->bp_hard[cpu]->bph_reg,
> > bp->bp_addr); }
> > - } else if (bp->bp_delay) {
> > + }
> > + } else if (!bp->bp_installed) {
> > + if (bp->bp_delay) {
> > if (KDB_DEBUG(BP))
> > kdb_printf("kdba_installbp delayed
> > bp\n"); kdba_handle_bp(regs, bp);
> > @@ -753,6 +869,8 @@ kdba_installbp(struct pt_regs *regs, kdb
> > int
> > kdba_removebp(kdb_bp_t *bp)
> > {
> > + int cpu = smp_processor_id();
> > +
> > /*
> > * For hardware breakpoints, remove it from the active
> > register,
> > * for software breakpoints, restore the instruction stream.
> ---------------------------
> Use http://oss.sgi.com/ecartis to modify your settings or to
> unsubscribe.
--
With Best Regards,
Konstantin Baydarov, Software Engineer
Montavista Russia
mail-to: kbaidarov at ru.mvista.com
---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.
More information about the kdb
mailing list