[kgtp] r1545 committed - Fix some bug of step

  • From: kgtp@xxxxxxxxxxxxxx
  • To: kgtp@xxxxxxxxxxxxx
  • Date: Mon, 06 May 2013 13:34:31 +0000

Revision: 1545
Author:   teawater
Date:     Mon May  6 06:34:14 2013
Log:      Fix some bug of step

http://code.google.com/p/kgtp/source/detail?r=1545

Modified:
 /trunk/gtp.c

=======================================
--- /trunk/gtp.c        Mon May  6 02:37:26 2013
+++ /trunk/gtp.c        Mon May  6 06:34:14 2013
@@ -99,6 +99,7 @@
 #include <linux/slab.h>
 #include <linux/ctype.h>
 #include <asm/atomic.h>
+#include <asm/debugreg.h>
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
 #include <linux/kdebug.h>
 #else
@@ -568,16 +569,16 @@
 {
        switch(reg) {
        case 0:
-               set_debugreg(val, 0);
+               gtp_set_debugreg(val, 0);
                break;
        case 1:
-               set_debugreg(val, 1);
+               gtp_set_debugreg(val, 1);
                break;
        case 2:
-               set_debugreg(val, 2);
+               gtp_set_debugreg(val, 2);
                break;
        case 3:
-               set_debugreg(val, 3);
+               gtp_set_debugreg(val, 3);
                break;
        }
 }
@@ -588,11 +589,11 @@
 {
        read_lock(&gtp_hwb_lock);
        __get_cpu_var(gtp_hwb_sync_count_local) = gtp_hwb_sync_count;
-       set_debugreg(0UL, 0);
-       set_debugreg(0UL, 1);
-       set_debugreg(0UL, 2);
-       set_debugreg(0UL, 3);
-       set_debugreg(GTP_HWB_DR7_DEF, 7);
+       gtp_set_debugreg(0UL, 0);
+       gtp_set_debugreg(0UL, 1);
+       gtp_set_debugreg(0UL, 2);
+       gtp_set_debugreg(0UL, 3);
+       gtp_set_debugreg(GTP_HWB_DR7_DEF, 7);
        read_unlock(&gtp_hwb_lock);
 }

@@ -600,11 +601,11 @@
 gtp_hwb_sync_local(void)
 {
        __get_cpu_var(gtp_hwb_sync_count_local) = gtp_hwb_sync_count;
-       set_debugreg(gtp_hwb_drx[0], 0);
-       set_debugreg(gtp_hwb_drx[1], 1);
-       set_debugreg(gtp_hwb_drx[2], 2);
-       set_debugreg(gtp_hwb_drx[3], 3);
-       set_debugreg(gtp_hwb_dr7, 7);
+       gtp_set_debugreg(gtp_hwb_drx[0], 0);
+       gtp_set_debugreg(gtp_hwb_drx[1], 1);
+       gtp_set_debugreg(gtp_hwb_drx[2], 2);
+       gtp_set_debugreg(gtp_hwb_drx[3], 3);
+       gtp_set_debugreg(gtp_hwb_dr7, 7);
 }

 static void
@@ -5611,25 +5612,74 @@
 }

 #ifdef CONFIG_X86
+#define ADDR_PREFIX_OPCODE 0x67
+#define DATA_PREFIX_OPCODE 0x66
+#define LOCK_PREFIX_OPCODE 0xf0
+#define CS_PREFIX_OPCODE 0x2e
+#define DS_PREFIX_OPCODE 0x3e
+#define ES_PREFIX_OPCODE 0x26
+#define FS_PREFIX_OPCODE 0x64
+#define GS_PREFIX_OPCODE 0x65
+#define SS_PREFIX_OPCODE 0x36
+#define REPNE_PREFIX_OPCODE 0xf2
+#define REPE_PREFIX_OPCODE  0xf3
+
 static int
 gtp_step_check_insn(struct pt_regs *regs)
 {
-       uint8_t         insn;
+       uint32_t        opcode;
+       uint8_t         opcode8;
        unsigned long   pc = GTP_REGS_PC(regs);

-       if (probe_kernel_read(&insn, (void *)pc, 1))
-               return -1;
+       /* prefixes */
+       while (1) {
+               if (probe_kernel_read(&opcode8, (void *)pc, 1))
+                       return -1;
+               pc++;
+               switch (opcode8) {
+               case REPE_PREFIX_OPCODE:
+               case REPNE_PREFIX_OPCODE:
+               case LOCK_PREFIX_OPCODE:
+               case CS_PREFIX_OPCODE:
+               case SS_PREFIX_OPCODE:
+               case DS_PREFIX_OPCODE:
+               case ES_PREFIX_OPCODE:
+               case FS_PREFIX_OPCODE:
+               case GS_PREFIX_OPCODE:
+               case DATA_PREFIX_OPCODE:
+               case ADDR_PREFIX_OPCODE:
+#ifndef CONFIG_X86_32
+               case 0x40 ... 0x4f:
+#endif
+                       break;
+               default:
+                       goto out_prefixes;
+               }
+       }
+out_prefixes:

-       switch (insn) {
+       opcode = (uint32_t)opcode8;
+reswitch:
+       switch (opcode) {
+       case 0x0f:
+               if (probe_kernel_read(&opcode8, (void *)pc, 1))
+                       return -1;
+               opcode = (uint32_t) opcode8 | 0x0f00;
+               goto reswitch;
+               break;
        case 0xfb:
                /* sti */
                __get_cpu_var(gtp_step).irq_need_open = 1;
-               GTP_REGS_PC(regs) += 1;
+               GTP_REGS_PC(regs) = pc;
                break;
        case 0xfa:
                /* cli */
                __get_cpu_var(gtp_step).irq_need_open = 0;
-               GTP_REGS_PC(regs) += 1;
+               GTP_REGS_PC(regs) = pc;
+               break;
+       case 0x0f07:
+               /* sysret */
+               return 1;
                break;
        };

@@ -5664,7 +5714,7 @@
 #else
        dr6 = args->err;
 #endif
-       set_debugreg(GTP_HWB_DR7_DEF, 7);
+       gtp_set_debugreg(GTP_HWB_DR7_DEF, 7);

        /* Handle while-stepping.  */
        spin_lock(&__get_cpu_var(gtp_step).lock);
@@ -5678,7 +5728,8 @@
                if (!__get_cpu_var(gtp_step).tpe || user_mode(args->regs))
                        gtp_step_stop(args->regs);
                else {
-                       if (gtp_step_check_insn(args->regs))
+                       int need_stop = gtp_step_check_insn(args->regs);
+                       if (need_stop < 0)
                                printk(KERN_WARNING "KGTP: check insn in %p got 
error.",
                                       (void *)GTP_REGS_PC(args->regs));

@@ -5694,7 +5745,7 @@
                        }
                        preempt_enable_no_resched();

-                       if (__get_cpu_var(gtp_step).step > 1) {
+                       if (__get_cpu_var(gtp_step).step > 1 && !need_stop) {
                                /* XXX: not sure need set eflags each step.  */
 #if 0
                                #if (LINUX_VERSION_CODE > 
KERNEL_VERSION(2,6,24))
@@ -5754,14 +5805,14 @@

        /* If the HWB need update in this CPU, just update it.  */
        if (__get_cpu_var(gtp_hwb_sync_count_local) != gtp_hwb_sync_count) {
-               set_debugreg(gtp_hwb_drx[0], 0);
-               set_debugreg(gtp_hwb_drx[1], 1);
-               set_debugreg(gtp_hwb_drx[2], 2);
-               set_debugreg(gtp_hwb_drx[3], 3);
+               gtp_set_debugreg(gtp_hwb_drx[0], 0);
+               gtp_set_debugreg(gtp_hwb_drx[1], 1);
+               gtp_set_debugreg(gtp_hwb_drx[2], 2);
+               gtp_set_debugreg(gtp_hwb_drx[3], 3);
                __get_cpu_var(gtp_hwb_sync_count_local) = gtp_hwb_sync_count;
        }

-       set_debugreg(gtp_hwb_dr7, 7);
+       gtp_set_debugreg(gtp_hwb_dr7, 7);
        read_unlock(&gtp_hwb_lock);
 #endif

@@ -5769,7 +5820,7 @@
 out:
 #endif
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
-       set_debugreg(dr6, 6);
+       gtp_set_debugreg(dr6, 6);
 #endif
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
        /* If have some other traps, let other handler handle it.  */
@@ -5967,7 +6018,7 @@

                /* Set gtp_hwb_dr7 and gtp_hwb_drx[num] to hwb.  */
                gtp_set_debugreg(gtp_hwb_drx[num], num);
-               set_debugreg(gtp_hwb_dr7, 7);
+               gtp_set_debugreg(gtp_hwb_dr7, 7);

                gtp_hwb_sync_count++;
                hwb->count = gtp_hwb_sync_count;
@@ -6024,7 +6075,7 @@
                        gtp_hwb_sync_count++;

                        /* Sync gtp_hwb_dr7 update to hwb.  */
-                       set_debugreg(gtp_hwb_dr7, 7);
+                       gtp_set_debugreg(gtp_hwb_dr7, 7);

 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
                        /* Send ipi to let other cpu update.  */

Other related posts:

  • » [kgtp] r1545 committed - Fix some bug of step - kgtp