mirror of https://gitee.com/openkylin/linux.git
x86: kretprobe-booster interrupt emulation code fix
Fix interrupt emulation code in kretprobe-booster according to pt_regs update (es/ds change and gs adding). This issue has been reported on systemtap-bugzilla: http://sources.redhat.com/bugzilla/show_bug.cgi?id=9965 | On a -tip kernel on x86_32, kretprobe_example (from samples) triggers the | following backtrace when its retprobing a class of functions that cause a | copy_from/to_user(). | | BUG: sleeping function called from invalid context at mm/memory.c:3196 | in_atomic(): 0, irqs_disabled(): 1, pid: 2286, name: cat Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Tested-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Cc: systemtap-ml <systemtap@sources.redhat.com> LKML-Reference: <49C7995C.2010601@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
a524446fe8
commit
fee039a1d0
|
@ -638,13 +638,13 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
|
|||
#else
|
||||
" pushf\n"
|
||||
/*
|
||||
* Skip cs, ip, orig_ax.
|
||||
* Skip cs, ip, orig_ax and gs.
|
||||
* trampoline_handler() will plug in these values
|
||||
*/
|
||||
" subl $12, %esp\n"
|
||||
" subl $16, %esp\n"
|
||||
" pushl %fs\n"
|
||||
" pushl %ds\n"
|
||||
" pushl %es\n"
|
||||
" pushl %ds\n"
|
||||
" pushl %eax\n"
|
||||
" pushl %ebp\n"
|
||||
" pushl %edi\n"
|
||||
|
@ -655,10 +655,10 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
|
|||
" movl %esp, %eax\n"
|
||||
" call trampoline_handler\n"
|
||||
/* Move flags to cs */
|
||||
" movl 52(%esp), %edx\n"
|
||||
" movl %edx, 48(%esp)\n"
|
||||
" movl 56(%esp), %edx\n"
|
||||
" movl %edx, 52(%esp)\n"
|
||||
/* Replace saved flags with true return address. */
|
||||
" movl %eax, 52(%esp)\n"
|
||||
" movl %eax, 56(%esp)\n"
|
||||
" popl %ebx\n"
|
||||
" popl %ecx\n"
|
||||
" popl %edx\n"
|
||||
|
@ -666,8 +666,8 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
|
|||
" popl %edi\n"
|
||||
" popl %ebp\n"
|
||||
" popl %eax\n"
|
||||
/* Skip ip, orig_ax, es, ds, fs */
|
||||
" addl $20, %esp\n"
|
||||
/* Skip ds, es, fs, gs, orig_ax and ip */
|
||||
" addl $24, %esp\n"
|
||||
" popf\n"
|
||||
#endif
|
||||
" ret\n");
|
||||
|
@ -691,6 +691,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
|||
regs->cs = __KERNEL_CS;
|
||||
#else
|
||||
regs->cs = __KERNEL_CS | get_kernel_rpl();
|
||||
regs->gs = 0;
|
||||
#endif
|
||||
regs->ip = trampoline_address;
|
||||
regs->orig_ax = ~0UL;
|
||||
|
|
Loading…
Reference in New Issue