On Mon, May 5, 2008 at 6:44 PM, Konstantin Baydarov
<[EMAIL PROTECTED]> wrote:
> Yes It's known issue.
> On Mon, 05 May 2008 13:06:11 +0300
> Avi Nehori <[EMAIL PROTECTED]> 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
> [EMAIL PROTECTED]:~#
> [EMAIL PROTECTED]:~# 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
> [EMAIL PROTECTED]:~#
>
> 1) Try CPU 0
> [EMAIL PROTECTED]:~#
> [EMAIL PROTECTED]:~# 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
> [EMAIL PROTECTED]:~#
> - OK
>
> 1) Try CPU 1
> [EMAIL PROTECTED]:~#
> [EMAIL PROTECTED]:~# taskset -c 1 sync
> [EMAIL PROTECTED]:~#
> - Doesn't work.
>
> Signed-off-by: Konstantin Baydarov <[EMAIL PROTECTED]>
> 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.