dr7 register enabled global but ran only once.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I used the dr0 register to trigger the int 1 exception when some
instruction fetched.
Even I enabled the global option in dr7,it still only run only once.
Any suggestions?
-----
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("example DR register.");

extern void my_debug_routine(void);

unsigned long ret_from_intr_p=0xc0102fc9; // ret_from_intr ,Got it
from /proc/kallsyms.

unsigned long old_debug_routine_p;
unsigned long my_debug_routine_p=(unsigned long)&my_debug_routine;

struct dr7_bit {
      unsigned gl0:2;  unsigned gl1:2;  unsigned gl2:2;  unsigned gl3:2;
      unsigned gle:2;  unsigned rsvd:1; unsigned non1:2; unsigned
gd:1; unsigned non0:2;
      unsigned rw0:2;  unsigned len0:2; unsigned rw1:2;  unsigned len1:2;
      unsigned rw2:2;  unsigned len2:2; unsigned rw3:2;  unsigned len3:2;
};

void open_debug_register(void)
{
      unsigned long rd0,rd7 = 0UL;
      struct dr7_bit *dr7;
      rd0 = ret_from_intr_p;
      dr7 = (struct dr7_bit *)&rd7;

      dr7->gle = 3;
      dr7->rsvd=1;

      dr7->len0 = 0;
      dr7->rw0 = 0;
      dr7->gl0 = 2;        // global enable.

    __asm__("mov %0,%%ebx \n\tmov %%ebx,%%dr7\n\tmov %1,%%ebx\n\tmov
%%ebx,%%dr0" ::"m"(rd7),"m"(rd0));

}

struct descriptor_idt
{
      unsigned short offset_low,seg_selector;
      unsigned char reserved,flag;
      unsigned short offset_high;
};

unsigned long counter=0UL;
void show_counter_value(void)
{
      printk("current counter is %lu\n",counter);
}

void my_debug_routine(void)
{
      __asm__ __volatile__("\n\taddl $1,%0\n\tjmp
*%1":"=m"(counter):"m"(old_debug_routine_p));
}

void update_idt_entry (int n, unsigned long *addr, int how)
{
      unsigned char idtr[6];
      struct descriptor_idt * idt_p;
      __asm__ __volatile__ ("sidt %0": "=m" (idtr));
      idt_p= &((struct descriptor_idt*)*(unsigned long*)&idtr[2])[n];
      switch (how){
              case 0:
                      *addr= (idt_p->offset_high <<16)+ idt_p->offset_low;
                      break;
              case 1:
                      idt_p->offset_high= (unsigned short)(*addr >> 16);
                      idt_p->offset_low = (unsigned short)(*addr & 0x0000ffff);
                      break;
      }
      return ;
}

int my_module_init(void)
{
      open_debug_register();
      update_idt_entry(1,&old_debug_routine_p,0);
      update_idt_entry(1,&my_debug_routine_p,1);
      return 0;
}

void my_module_exit(void)
{
      update_idt_entry(1,&old_debug_routine_p,1);
      show_counter_value();
      return ;
}

module_init(my_module_init);
module_exit(my_module_exit);
-
To unsubscribe from this list: send the line "unsubscribe linux-apps" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux