Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ecc798c authored by Roland McGrath's avatar Roland McGrath Committed by Ingo Molnar
Browse files

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: default avatarRoland McGrath <roland@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 10faa81e
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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;
}

+14 −0
Original line number Diff line number Diff line
@@ -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;
}