lkml.org 
[lkml]   [2007]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 26/27] x86: debugctlmsr kprobes
    Date

    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 <roland@redhat.com>
    ---
    arch/x86/kernel/kprobes_32.c | 15 +++++++++++++++
    arch/x86/kernel/kprobes_64.c | 15 +++++++++++++++
    2 files changed, 30 insertions(+), 0 deletions(-)

    diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
    index d87a523..f151f06 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 3db3611..d3be418 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*/
    @@ -534,6 +547,8 @@ static void __kprobes resume_execution(struct kprobe *p,
    } else {
    regs->rip = orig_rip + (regs->rip - copy_rip);
    }
    +
    + restore_btf();
    }

    int __kprobes post_kprobe_handler(struct pt_regs *regs)
    -
    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/
    \
     
     \ /
      Last update: 2007-11-25 23:11    [W:0.023 / U:1.148 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site