Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1ecc798c67645e0ee6eb028cb988b71b3edf4b40
Commit:     1ecc798c67645e0ee6eb028cb988b71b3edf4b40
Parent:     10faa81e102e2b7695f386812055cd2ef9e44b4c
Author:     Roland McGrath <[EMAIL PROTECTED]>
AuthorDate: Wed Jan 30 13:30:54 2008 +0100
Committer:  Ingo Molnar <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 13:30:54 2008 +0100

    x86: debugctlmsr kprobes
    
    This adjusts the x86 kprobes implementation to cope with per-thread
    MSR_IA32_DEBUGCTLMSR being set for user mode.  I haven't delved deep
    enough into the kprobes code to be really sure this covers all the
    cases where the user-mode BTF setting needs to be cleared or restored.
    It looks about right to me.
    
    Signed-off-by: Roland McGrath <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
---
 arch/x86/kernel/kprobes_32.c |   15 +++++++++++++++
 arch/x86/kernel/kprobes_64.c |   14 ++++++++++++++
 2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
index 3a020f7..bc4a683 100644
--- a/arch/x86/kernel/kprobes_32.c
+++ b/arch/x86/kernel/kprobes_32.c
@@ -217,8 +217,21 @@ static void __kprobes set_current_kprobe(struct kprobe *p, 
struct pt_regs *regs,
                kcb->kprobe_saved_eflags &= ~IF_MASK;
 }
 
+static __always_inline void clear_btf(void)
+{
+       if (test_thread_flag(TIF_DEBUGCTLMSR))
+               wrmsr(MSR_IA32_DEBUGCTLMSR, 0, 0);
+}
+
+static __always_inline void restore_btf(void)
+{
+       if (test_thread_flag(TIF_DEBUGCTLMSR))
+               wrmsr(MSR_IA32_DEBUGCTLMSR, current->thread.debugctlmsr, 0);
+}
+
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs 
*regs)
 {
+       clear_btf();
        regs->eflags |= TF_MASK;
        regs->eflags &= ~IF_MASK;
        /*single step inline if the instruction is an int3*/
@@ -542,6 +555,8 @@ static void __kprobes resume_execution(struct kprobe *p,
        regs->eip = orig_eip + (regs->eip - copy_eip);
 
 no_change:
+       restore_btf();
+
        return;
 }
 
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
index 5df19a9..10d66e3 100644
--- a/arch/x86/kernel/kprobes_64.c
+++ b/arch/x86/kernel/kprobes_64.c
@@ -256,8 +256,21 @@ static void __kprobes set_current_kprobe(struct kprobe *p, 
struct pt_regs *regs,
                kcb->kprobe_saved_rflags &= ~IF_MASK;
 }
 
+static __always_inline void clear_btf(void)
+{
+       if (test_thread_flag(TIF_DEBUGCTLMSR))
+               wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
+}
+
+static __always_inline void restore_btf(void)
+{
+       if (test_thread_flag(TIF_DEBUGCTLMSR))
+               wrmsrl(MSR_IA32_DEBUGCTLMSR, current->thread.debugctlmsr);
+}
+
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs 
*regs)
 {
+       clear_btf();
        regs->eflags |= TF_MASK;
        regs->eflags &= ~IF_MASK;
        /*single step inline if the instruction is an int3*/
@@ -527,6 +540,7 @@ static void __kprobes resume_execution(struct kprobe *p,
 
        regs->rip = orig_rip + (regs->rip - copy_rip);
 no_change:
+       restore_btf();
 
        return;
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to