public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* A correct method to use the x86 breakpoint registers (DR0-7)
@ 2005-07-05 16:20 Jeff Carr
  2005-07-05 21:43 ` kprobe support for memory access watchpoints Jeff Carr
  2005-07-07  4:58 ` A correct method to use the x86 breakpoint registers (DR0-7) Jeff Carr
  0 siblings, 2 replies; 4+ messages in thread
From: Jeff Carr @ 2005-07-05 16:20 UTC (permalink / raw)
  To: linux-kernel

I'm trying to set the x86 breakpoint registers to trip on write data.

After they are set, nothing seems to happen when I trigger them.

It's possible I'm not setting them correctly, I tried putting the
virt_to_phys() value in them. And, I tried looking at what KPROBE puts
in them, but it looks like kprobe doesn't use them at all.

In 2.6.11, arch/i386/ has 5 places where it modifies the db regs:
	do_debug()              in traps.c    (??)
	do_signal()             in signal.c   (re-enable them)
	fix_processor_context() in cpu.c      (reload them)
	__switch_to()		in process.c  (reload them)
	cpu_init()		in common.c   (clears them)

Just FYI: sometime after 2.6.11, the macros get_debugreg() and
set_debugreg() were defined in include/asm-i386/processor.h and set to
be used in the 5 places above. In any case, the functionality seems the
same the above routines. (And the registers names corrected s/db/dr/g )

In any case, setting these registers never seems to do anything. No INT3
or INT1 (is it really supposed to generate an interrupt?) Perhaps I need
to have kgdb setup.

The closest I can get to making anything happen is if I set bit 13 of
DR7 (triggers on the next access of the breakpoint registers) then when
I insmod I get:

root@foxtrot:~/dbregtest# insmod ./dbregtest.ko
Trace/breakpoint trap
root@foxtrot:~/dbregtest#

If I set BR0 with the value from virt_to_phys() I don't get this
trace/breakpoint trap.

Enjoy,
Jeff

// Current documentation for these registers is in Vol 3 Section 15.2:
// Also note: EFLAGS BIT 16 (Resume) section 2.3 disables #DB exceptions
// http://developer.intel.com/design/pentium4/manuals/index_new.htm

static int __init db_reg_test(void)
{
        u32 *i;
        unsigned int phys_addr;

        i = kmalloc( 0x1000, GFP_DMA );
        printk("i == 0x%08X\n", (int) i);
        phys_addr = virt_to_phys(i);

        printk("virt_to_phys(i)  == 0x%08X\n", (int) phys_addr);
        __asm__ __volatile__( "movl %0, %%dr0\n" : : "r" (phys_addr) );

        // clear out the DR6 status register
        __asm__ __volatile__( "movl %0, %%dr6\n" : : "r" (0xFFFF0FF0) );

        // Enable DR0 as a global breakpoint
        __asm__ __volatile__( "movl %0, %%dr7\n" : : "r" (0x00030002) );

        // Enables all four BR registers as global breakpoints
        __asm__ __volatile__( "movl %0, %%dr7\n" : : "r" (0x333300AA) );

        // shouldn't this trigger a breakpoint exception?
        i[0] = 0xDEADBEEF;

        kfree(i);

	// this will correctly trigger a breakpoint
	// __asm__ ( "movl %0, %%dr7\n" : : "r" (0x333320AA) );
        // __asm__ ( "movl %0, %%dr7\n" : : "r" (0x333300AA) );
        return 0;
}

module_init(db_reg_test);

root@foxtrot:~/dbregtest# tail /var/log/kern.log
Jul  5 09:01:16 localhost kernel: i == 0xC046E000
Jul  5 09:01:16 localhost kernel: virt_to_phys(i)  == 0x0046E000




^ permalink raw reply	[flat|nested] 4+ messages in thread

* kprobe support for memory access watchpoints
  2005-07-05 16:20 A correct method to use the x86 breakpoint registers (DR0-7) Jeff Carr
@ 2005-07-05 21:43 ` Jeff Carr
  2005-07-06  5:59   ` Prasanna S Panchamukhi
  2005-07-07  4:58 ` A correct method to use the x86 breakpoint registers (DR0-7) Jeff Carr
  1 sibling, 1 reply; 4+ messages in thread
From: Jeff Carr @ 2005-07-05 21:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: Hien Nguyen, Jim Keniston, Prasanna S Panchamukhi

I was wondering if there are plans to support a method to register
watchpoints for memory data access with kprobe. On x86, it's possible to
watch for read/write access to arbitrary memory locations via DR memory
registers.

Perhaps register_kprobe() could be modified to support this or perhaps
some new function. This would probably be difficult based on how
differently kprobe works vs. how the DR registers work. I thought I
would send an email because you might be doing or thinking something
similar.

Enjoy,
Jeff

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: kprobe support for memory access watchpoints
  2005-07-05 21:43 ` kprobe support for memory access watchpoints Jeff Carr
@ 2005-07-06  5:59   ` Prasanna S Panchamukhi
  0 siblings, 0 replies; 4+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-06  5:59 UTC (permalink / raw)
  To: Jeff Carr; +Cc: linux-kernel, Hien Nguyen, Jim Keniston

Jeff,

> I was wondering if there are plans to support a method to register
> watchpoints for memory data access with kprobe. On x86, it's possible to
> watch for read/write access to arbitrary memory locations via DR memory
> registers.

Here are couple of patches providing debug register allocation
mechanism and kernel API to register watchpoints. These patches were
posted and reviewed on lkml some time back, Please see the URL
below for details.

http://seclists.org/lists/linux-kernel/2004/Oct/4730.html
http://seclists.org/lists/linux-kernel/2004/Oct/4729.html


Thanks
Prasanna
-- 

Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Ph: 91-80-25044636
<prasanna@in.ibm.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: A correct method to use the x86 breakpoint registers (DR0-7)
  2005-07-05 16:20 A correct method to use the x86 breakpoint registers (DR0-7) Jeff Carr
  2005-07-05 21:43 ` kprobe support for memory access watchpoints Jeff Carr
@ 2005-07-07  4:58 ` Jeff Carr
  1 sibling, 0 replies; 4+ messages in thread
From: Jeff Carr @ 2005-07-07  4:58 UTC (permalink / raw)
  To: linux-kernel, Keith Owens

I setup KDB with 2.6.13-rc1. It works well. continuing past a BUG() is
potentially very useful. Well, it's at least fun to see it happen :)

I wanted to set the BR0/7 registers from within running code. I thought
that would trigger KDB, but it doesn't. It seems that the breakpoint
trap is passed through the kernel and into userspace and caught by
glibc. I tried to track this down, but am lost in how or where a int3
actually is handled.

I looked through the Documentation/kdb/ man pages (they are nice) but
didn't see anything on how one might register a breakpoint with KDB from
 some exported function.

The kprobe guys have a patch that I can use to try to solve my problem
(described below), but I thought I would try kdb some more before I
switched to trying kprobe.

Thanks,
Jeff

BTW, I don't know enough about kbuild, but if it is possible, you might
want to force CONFIG_KPROBE off when you have kdb enabled or you get
duplicate do_int3() functions defined in arch/i386/traps.c



On 07/05/2005 09:20 AM, Jeff Carr wrote:
> I'm trying to set the x86 breakpoint registers to trip on write data.
> 
> After they are set, nothing seems to happen when I trigger them.
> 
> It's possible I'm not setting them correctly, I tried putting the
> virt_to_phys() value in them. And, I tried looking at what KPROBE puts
> in them, but it looks like kprobe doesn't use them at all.
> 
> In 2.6.11, arch/i386/ has 5 places where it modifies the db regs:
> 	do_debug()              in traps.c    (??)
> 	do_signal()             in signal.c   (re-enable them)
> 	fix_processor_context() in cpu.c      (reload them)
> 	__switch_to()		in process.c  (reload them)
> 	cpu_init()		in common.c   (clears them)
> 
> Just FYI: sometime after 2.6.11, the macros get_debugreg() and
> set_debugreg() were defined in include/asm-i386/processor.h and set to
> be used in the 5 places above. In any case, the functionality seems the
> same the above routines. (And the registers names corrected s/db/dr/g )
> 
> In any case, setting these registers never seems to do anything. No INT3
> or INT1 (is it really supposed to generate an interrupt?) Perhaps I need
> to have kgdb setup.
> 
> The closest I can get to making anything happen is if I set bit 13 of
> DR7 (triggers on the next access of the breakpoint registers) then when
> I insmod I get:
> 
> root@foxtrot:~/dbregtest# insmod ./dbregtest.ko
> Trace/breakpoint trap
> root@foxtrot:~/dbregtest#
> 
> If I set BR0 with the value from virt_to_phys() I don't get this
> trace/breakpoint trap.
> 
> Enjoy,
> Jeff
> 
> // Current documentation for these registers is in Vol 3 Section 15.2:
> // Also note: EFLAGS BIT 16 (Resume) section 2.3 disables #DB exceptions
> // http://developer.intel.com/design/pentium4/manuals/index_new.htm
> 
> static int __init db_reg_test(void)
> {
>         u32 *i;
>         unsigned int phys_addr;
> 
>         i = kmalloc( 0x1000, GFP_DMA );
>         printk("i == 0x%08X\n", (int) i);
>         phys_addr = virt_to_phys(i);
> 
>         printk("virt_to_phys(i)  == 0x%08X\n", (int) phys_addr);
>         __asm__ __volatile__( "movl %0, %%dr0\n" : : "r" (phys_addr) );
> 
>         // clear out the DR6 status register
>         __asm__ __volatile__( "movl %0, %%dr6\n" : : "r" (0xFFFF0FF0) );
> 
>         // Enable DR0 as a global breakpoint
>         __asm__ __volatile__( "movl %0, %%dr7\n" : : "r" (0x00030002) );
> 
>         // Enables all four BR registers as global breakpoints
>         __asm__ __volatile__( "movl %0, %%dr7\n" : : "r" (0x333300AA) );
> 
>         // shouldn't this trigger a breakpoint exception?
>         i[0] = 0xDEADBEEF;
> 
>         kfree(i);
> 
> 	// this will correctly trigger a breakpoint
> 	// __asm__ ( "movl %0, %%dr7\n" : : "r" (0x333320AA) );
>         // __asm__ ( "movl %0, %%dr7\n" : : "r" (0x333300AA) );
>         return 0;
> }
> 
> module_init(db_reg_test);
> 
> root@foxtrot:~/dbregtest# tail /var/log/kern.log
> Jul  5 09:01:16 localhost kernel: i == 0xC046E000
> Jul  5 09:01:16 localhost kernel: virt_to_phys(i)  == 0x0046E000
> 
> 
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-07-07  4:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-05 16:20 A correct method to use the x86 breakpoint registers (DR0-7) Jeff Carr
2005-07-05 21:43 ` kprobe support for memory access watchpoints Jeff Carr
2005-07-06  5:59   ` Prasanna S Panchamukhi
2005-07-07  4:58 ` A correct method to use the x86 breakpoint registers (DR0-7) Jeff Carr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox