From: "bibo,mao" <bibo_mao@linux.intel.com>
To: prasanna@in.ibm.com
Cc: linux-kernel@vger.kernel.org, systemtap@sources.redhat.com,
akpm@osdl.org, Andi Kleen <ak@suse.de>,
davem@davemloft.net, suparna@in.ibm.com,
richardj_moore@uk.ibm.com
Subject: Re: [RFC] [PATCH 5/6] Kprobes: Single step the original instruction out-of-line
Date: Wed, 10 May 2006 00:47:00 -0000 [thread overview]
Message-ID: <44613812.1070100@linux.intel.com> (raw)
In-Reply-To: <20060509071204.GE22493@in.ibm.com>
Previously when I tested uprobe patch in some specific IA32 machine with
CONFIG_X86_PAE option on, uprobe can not be activated unless kernel
option "noexec=off" is added before booting kernel.
Because without this option user stack is non-executable, copied trap
instruction is placed in process's stack space. Executing trap
instrunction in stack will cause page fault of non-execution priviledge.
Thanks
bibo,mao
Prasanna S Panchamukhi ??:
> This patch provides a mechanism for probe handling and
> executing the user-specified handlers.
>
> Each userspace probe is uniquely identified by the combination of
> inode and offset, hence during registration the inode and offset
> combination is added to uprobes hash table. Initially when
> breakpoint instruction is hit, the uprobes hash table is looked up
> for matching inode and offset. The pre_handlers are called in
> sequence if multiple probes are registered. Similar to kprobes,
> uprobes also adopts to single step out-of-line, so that probe miss in
> SMP environment can be avoided. But for userspace probes, instruction
> copied into kernel address space cannot be single stepped, hence the
> instruction must be copied to user address space. The solution is to
> find free space in the current process address space and then copy the
> original instruction and single step that instruction.
>
> User processes use stack space to store local variables, arguments and
> return values. Normally the stack space either below or above the
> stack pointer indicates the free stack space.
>
> The instruction to be single stepped can modify the stack space,
> hence before using the free stack space, sufficient stack space must
> be left. The instruction is copied to the bottom of the page and check
> is made such that the copied instruction does not cross the page
> boundary. The copied instruction is then single stepped. Several
> architectures does not allow the instruction to be executed from the
> stack location, since no-exec bit is set for the stack pages. In those
> architectures, the page table entry corresponding to the stack page is
> identified and the no-exec bit is unset making the instruction on that
> stack page to be executed.
>
> There are situations where even the free stack space is not enough for
> the user instruction to be copied and single stepped. In such
> situations, the virtual memory area(vma) can be expanded beyond the
> current stack vma. This expanded stack can be used to copy the
> original instruction and single step out-of-line.
>
> Even if the vma cannot be extended, then the instruction much be
> executed inline, by replacing the breakpoint instruction with the
> original instruction.
>
> Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
>
>
> arch/i386/kernel/Makefile | 2
> arch/i386/kernel/kprobes.c | 4
> arch/i386/kernel/uprobes.c | 472 +++++++++++++++++++++++++++++++++++++++++++++
> arch/i386/mm/fault.c | 3
> include/asm-i386/kprobes.h | 21 ++
> 5 files changed, 497 insertions(+), 5 deletions(-)
>
> diff -puN include/asm-i386/kprobes.h~kprobes_userspace_probes-ss-out-of-line include/asm-i386/kprobes.h
> --- linux-2.6.17-rc3-mm1/include/asm-i386/kprobes.h~kprobes_userspace_probes-ss-out-of-line 2006-05-09 12:40:48.000000000 +0530
> +++ linux-2.6.17-rc3-mm1-prasanna/include/asm-i386/kprobes.h 2006-05-09 12:40:48.000000000 +0530
> @@ -26,6 +26,7 @@
> */
> #include <linux/types.h>
> #include <linux/ptrace.h>
> +#include <asm/cacheflush.h>
>
> #define __ARCH_WANT_KPROBES_INSN_SLOT
>
> @@ -78,6 +79,19 @@ struct kprobe_ctlblk {
> struct prev_kprobe prev_kprobe;
> };
>
> +/* per user probe control block */
> +struct uprobe_ctlblk {
> + unsigned long uprobe_status;
> + unsigned long uprobe_saved_eflags;
> + unsigned long uprobe_old_eflags;
> + unsigned long singlestep_addr;
> + unsigned long flags;
> + struct kprobe *curr_p;
> + pte_t *upte;
> + struct page *upage;
> + struct task_struct *tsk;
> +};
> +
> /* trap3/1 are intr gates for kprobes. So, restore the status of IF,
> * if necessary, before executing the original int3/1 (trap) handler.
> */
> @@ -89,4 +103,11 @@ static inline void restore_interrupts(st
>
> extern int kprobe_exceptions_notify(struct notifier_block *self,
> unsigned long val, void *data);
> +extern int uprobe_exceptions_notify(struct notifier_block *self,
> + unsigned long val, void *data);
> +extern unsigned long get_segment_eip(struct pt_regs *regs,
> + unsigned long *eip_limit);
> +extern int is_IF_modifier(kprobe_opcode_t opcode);
> +
> +extern pte_t *get_one_pte(unsigned long address);
> #endif /* _ASM_KPROBES_H */
> diff -puN arch/i386/kernel/uprobes.c~kprobes_userspace_probes-ss-out-of-line arch/i386/kernel/uprobes.c
> --- linux-2.6.17-rc3-mm1/arch/i386/kernel/uprobes.c~kprobes_userspace_probes-ss-out-of-line 2006-05-09 12:40:48.000000000 +0530
> +++ linux-2.6.17-rc3-mm1-prasanna/arch/i386/kernel/uprobes.c 2006-05-09 12:40:48.000000000 +0530
> @@ -30,6 +30,10 @@
> #include <asm/cacheflush.h>
> #include <asm/kdebug.h>
> #include <asm/desc.h>
> +#include <asm/uaccess.h>
> +
> +static struct uprobe_ctlblk uprobe_ctlblk;
> +struct uprobe *current_uprobe;
>
> int __kprobes arch_alloc_insn(struct kprobe *p)
> {
> @@ -69,3 +73,471 @@ int __kprobes arch_copy_uprobe(struct kp
>
> return ret;
> }
> +
> +/*
> + * This routine check for space in the process's stack address space.
> + * If enough address space is found, returns the address of free stack
> + * space.
> + */
> +unsigned long __kprobes *find_stack_space_on_next_page(unsigned long stack_addr,
> + int size, struct vm_area_struct *vma)
> +{
> + unsigned long addr;
> + struct page *pg;
> + int retval = 0;
> +
> + if (((stack_addr - sizeof(long long))) < (vma->vm_start + size))
> + return NULL;
> + addr = (stack_addr & PAGE_MASK) + PAGE_SIZE;
> +
> + retval = get_user_pages(current, current->mm,
> + (unsigned long )addr, 1, 1, 0, &pg, NULL);
> + if (retval)
> + return NULL;
> +
> + return (unsigned long *) addr;
> +}
> +
> +/*
> + * This routine expands the stack beyond the present process address
> + * space and returns the address of free stack space. This routine
> + * must be called with mmap_sem held.
> + */
> +unsigned long __kprobes *find_stack_space_in_expanded_vma(int size,
> + struct vm_area_struct *vma)
> +{
> + unsigned long addr, vm_addr;
> + int retval = 0;
> + struct vm_area_struct *new_vma;
> + struct mm_struct *mm = current->mm;
> + struct page *pg;
> +
> + vm_addr = vma->vm_start - size;
> + new_vma = find_extend_vma(mm, vm_addr);
> + if (!new_vma)
> + return NULL;
> +
> + addr = new_vma->vm_start;
> + retval = get_user_pages(current, current->mm,
> + (unsigned long )addr, 1, 1, 0, &pg, NULL);
> + if (retval)
> + return NULL;
> +
> + return (unsigned long *) addr;
> +}
> +
> +/*
> + * This routine checks for stack free space below the stack pointer in the
> + * current stack page. If there is not enough stack space, it returns NULL.
> + */
> +unsigned long __kprobes *find_stack_space_on_curr_page(unsigned long stack_addr,
> + int size)
> +{
> + unsigned long page_addr;
> +
> + page_addr = stack_addr & PAGE_MASK;
> +
> + if (((stack_addr - sizeof(long long))) < (page_addr + size))
> + return NULL;
> +
> + return (unsigned long *) page_addr;
> +}
> +
> +/*
> + * This routines finds free stack space for a given size either on the
> + * current stack page, or on next stack page. If there is no free stack
> + * space is availible, then expands the stack and returns the address of
> + * free stack space.
> + */
> +unsigned long __kprobes *find_stack_space(unsigned long stack_addr, int size)
> +{
> + unsigned long *addr;
> + struct vm_area_struct *vma = NULL;
> +
> + addr = find_stack_space_on_curr_page(stack_addr, size);
> + if (addr)
> + return addr;
> +
> + if (!down_read_trylock(¤t->mm->mmap_sem))
> + down_read(¤t->mm->mmap_sem);
> +
> + vma = find_vma(current->mm, (stack_addr & PAGE_MASK));
> + if (!vma) {
> + up_read(¤t->mm->mmap_sem);
> + return NULL;
> + }
> +
> + addr = find_stack_space_on_next_page(stack_addr, size, vma);
> + if (addr) {
> + up_read(¤t->mm->mmap_sem);
> + return addr;
> + }
> +
> + addr = find_stack_space_in_expanded_vma(size, vma);
> + up_read(¤t->mm->mmap_sem);
> +
> + if (!addr)
> + return NULL;
> +
> + return addr;
> +}
> +
> +/*
> + * This routines get the page containing the probe, maps it and
> + * replaced the instruction at the probed address with specified
> + * opcode.
> + */
> +void __kprobes replace_original_insn(struct uprobe *uprobe,
> + struct pt_regs *regs, kprobe_opcode_t opcode)
> +{
> + kprobe_opcode_t *addr;
> + struct page *page;
> +
> + page = find_get_page(uprobe->inode->i_mapping,
> + uprobe->offset >> PAGE_CACHE_SHIFT);
> + BUG_ON(!page);
> +
> + addr = (kprobe_opcode_t *)kmap_atomic(page, KM_USER1);
> + addr = (kprobe_opcode_t *)((unsigned long)addr +
> + (unsigned long)(uprobe->offset & ~PAGE_MASK));
> + *addr = opcode;
> + /*TODO: flush vma ? */
> + kunmap_atomic(addr, KM_USER1);
> +
> + flush_dcache_page(page);
> +
> + if (page)
> + page_cache_release(page);
> + regs->eip = (unsigned long)uprobe->kp.addr;
> +}
> +
> +/*
> + * This routine provides the functionality of single stepping
> + * out-of-line. If single stepping out-of-line cannot be achieved,
> + * it replaces with the original instruction allowing it to single
> + * step inline.
> + */
> +static int __kprobes prepare_singlestep_uprobe(struct uprobe *uprobe,
> + struct uprobe_ctlblk *ucb, struct pt_regs *regs)
> +{
> + unsigned long *addr = NULL, stack_addr = regs->esp;
> + int size = sizeof(kprobe_opcode_t) * MAX_INSN_SIZE;
> + unsigned long *source = (unsigned long *)uprobe->kp.ainsn.insn;
> +
> + /*
> + * Get free stack space to copy original instruction, so as to
> + * single step out-of-line.
> + */
> + addr = find_stack_space(stack_addr, size);
> + if (!addr)
> + goto no_stack_space;
> +
> + /*
> + * We are in_atomic and preemption is disabled at this point of
> + * time. Copy original instruction on this per process stack
> + * page so as to single step out-of-line.
> + */
> + if (__copy_to_user_inatomic((unsigned long *)addr, source, size))
> + goto no_stack_space;
> +
> + regs->eip = (unsigned long)addr;
> +
> + regs->eflags |= TF_MASK;
> + regs->eflags &= ~IF_MASK;
> + ucb->uprobe_status = UPROBE_HIT_SS;
> +
> + ucb->upte = get_one_pte(regs->eip);
> + if (!ucb->upte)
> + goto no_stack_space;
> + ucb->upage = pte_page(*ucb->upte);
> + set_pte(ucb->upte, pte_mkdirty(*ucb->upte));
> + ucb->singlestep_addr = regs->eip;
> +
> + return 0;
> +
> +no_stack_space:
> + replace_original_insn(uprobe, regs, uprobe->kp.opcode);
> + ucb->uprobe_status = UPROBE_SS_INLINE;
> + ucb->singlestep_addr = regs->eip;
> +
> + return 0;
> +}
> +
> +/*
> + * uprobe_handler() executes the user specified handler and setup for
> + * single stepping the original instruction either out-of-line or inline.
> + */
> +static int __kprobes uprobe_handler(struct pt_regs *regs)
> +{
> + struct kprobe *p;
> + int ret = 0;
> + kprobe_opcode_t *addr = NULL;
> + struct uprobe_ctlblk *ucb = &uprobe_ctlblk;
> + unsigned long limit;
> +
> + spin_lock_irqsave(&uprobe_lock, ucb->flags);
> + /* preemption is disabled, remains disabled
> + * until we single step on original instruction.
> + */
> + inc_preempt_count();
> +
> + addr = (kprobe_opcode_t *)(get_segment_eip(regs, &limit) - 1);
> +
> + p = get_uprobe(addr);
> + if (!p) {
> +
> + if (*addr != BREAKPOINT_INSTRUCTION) {
> + /*
> + * The breakpoint instruction was removed right
> + * after we hit it. Another cpu has removed
> + * either a probe point or a debugger breakpoint
> + * at this address. In either case, no further
> + * handling of this interrupt is appropriate.
> + * Back up over the (now missing) int3 and run
> + * the original instruction.
> + */
> + regs->eip -= sizeof(kprobe_opcode_t);
> + ret = 1;
> + }
> + /* Not one of ours: let kernel handle it */
> + goto no_uprobe;
> + }
> +
> + if (p->opcode == BREAKPOINT_INSTRUCTION) {
> + /*
> + * Breakpoint was already present even before the probe
> + * was inserted, this might break some compatibility with
> + * other debuggers like gdb etc. We dont handle such probes.
> + */
> + current_uprobe = NULL;
> + goto no_uprobe;
> + }
> +
> + ucb->curr_p = p;
> + ucb->tsk = current;
> + ucb->uprobe_status = UPROBE_HIT_ACTIVE;
> + ucb->uprobe_saved_eflags = (regs->eflags & (TF_MASK | IF_MASK));
> + ucb->uprobe_old_eflags = (regs->eflags & (TF_MASK | IF_MASK));
> +
> + if (p->pre_handler && p->pre_handler(p, regs))
> + /* handler has already set things up, so skip ss setup */
> + return 1;
> +
> + prepare_singlestep_uprobe(current_uprobe, ucb, regs);
> + /*
> + * Avoid scheduling the current while returning from
> + * kernel to user mode.
> + */
> + clear_need_resched();
> + return 1;
> +
> +no_uprobe:
> + spin_unlock_irqrestore(&uprobe_lock, ucb->flags);
> + dec_preempt_count();
> +
> + return ret;
> +}
> +
> +/*
> + * Called after single-stepping. p->addr is the address of the
> + * instruction whose first byte has been replaced by the "int 3"
> + * instruction. To avoid the SMP problems that can occur when we
> + * temporarily put back the original opcode to single-step, we
> + * single-stepped a copy of the instruction. The address of this
> + * copy is p->ainsn.insn.
> + *
> + * This function prepares to return from the post-single-step
> + * interrupt. We have to fix up the stack as follows:
> + *
> + * 0) Typically, the new eip is relative to the copied instruction. We
> + * need to make it relative to the original instruction. Exceptions are
> + * return instructions and absolute or indirect jump or call instructions.
> + *
> + * 1) If the single-stepped instruction was pushfl, then the TF and IF
> + * flags are set in the just-pushed eflags, and may need to be cleared.
> + *
> + * 2) If the single-stepped instruction was a call, the return address
> + * that is atop the stack is the address following the copied instruction.
> + * We need to make it the address following the original instruction.
> + */
> +static void __kprobes resume_execution_user(struct kprobe *p,
> + struct pt_regs *regs, struct uprobe_ctlblk *ucb)
> +{
> + unsigned long *tos = (unsigned long *)regs->esp;
> + unsigned long next_eip = 0;
> + unsigned long copy_eip = ucb->singlestep_addr;
> + unsigned long orig_eip = (unsigned long)p->addr;
> +
> + switch (p->ainsn.insn[0]) {
> + case 0x9c: /* pushfl */
> + *tos &= ~(TF_MASK | IF_MASK);
> + *tos |= ucb->uprobe_old_eflags;
> + break;
> + case 0xc3: /* ret/lret */
> + case 0xcb:
> + case 0xc2:
> + case 0xca:
> + next_eip = regs->eip;
> + /* eip is already adjusted, no more changes required*/
> + break;
> + case 0xe8: /* call relative - Fix return addr */
> + *tos = orig_eip + (*tos - copy_eip);
> + break;
> + case 0xff:
> + if ((p->ainsn.insn[1] & 0x30) == 0x10) {
> + /* call absolute, indirect */
> + /* Fix return addr; eip is correct. */
> + next_eip = regs->eip;
> + *tos = orig_eip + (*tos - copy_eip);
> + } else if (((p->ainsn.insn[1] & 0x31) == 0x20) ||
> + ((p->ainsn.insn[1] & 0x31) == 0x21)) {
> + /* jmp near or jmp far absolute indirect */
> + /* eip is correct. */
> + next_eip = regs->eip;
> + }
> + break;
> + case 0xea: /* jmp absolute -- eip is correct */
> + next_eip = regs->eip;
> + break;
> + default:
> + break;
> + }
> +
> + regs->eflags &= ~TF_MASK;
> + if (next_eip)
> + regs->eip = next_eip;
> + else
> + regs->eip = orig_eip + (regs->eip - copy_eip);
> +}
> +
> +/*
> + * post_uprobe_handler(), executes the user specified handlers and
> + * resumes with the normal execution.
> + */
> +static int __kprobes post_uprobe_handler(struct pt_regs *regs)
> +{
> + struct kprobe *cur;
> + struct uprobe_ctlblk *ucb;
> +
> + if (!current_uprobe)
> + return 0;
> +
> + ucb = &uprobe_ctlblk;
> + cur = ucb->curr_p;
> +
> + if (!cur || ucb->tsk != current)
> + return 0;
> +
> + if (cur->post_handler) {
> + if (ucb->uprobe_status == UPROBE_SS_INLINE)
> + ucb->uprobe_status = UPROBE_SSDONE_INLINE;
> + else
> + ucb->uprobe_status = UPROBE_HIT_SSDONE;
> + cur->post_handler(cur, regs, 0);
> + }
> +
> + resume_execution_user(cur, regs, ucb);
> + regs->eflags |= ucb->uprobe_saved_eflags;
> +
> + if (ucb->uprobe_status == UPROBE_SSDONE_INLINE)
> + replace_original_insn(current_uprobe, regs,
> + BREAKPOINT_INSTRUCTION);
> + else
> + pte_unmap(ucb->upte);
> +
> + current_uprobe = NULL;
> + spin_unlock_irqrestore(&uprobe_lock, ucb->flags);
> + dec_preempt_count();
> + /*
> + * if somebody else is single stepping across a probe point, eflags
> + * will have TF set, in which case, continue the remaining processing
> + * of do_debug, as if this is not a probe hit.
> + */
> + if (regs->eflags & TF_MASK)
> + return 0;
> +
> + return 1;
> +}
> +
> +static int __kprobes uprobe_fault_handler(struct pt_regs *regs, int trapnr)
> +{
> + struct kprobe *cur;
> + struct uprobe_ctlblk *ucb;
> + int ret = 0;
> +
> + ucb = &uprobe_ctlblk;
> + cur = ucb->curr_p;
> +
> + if (ucb->tsk != current || !cur)
> + return 0;
> +
> + switch(ucb->uprobe_status) {
> + case UPROBE_HIT_SS:
> + pte_unmap(ucb->upte);
> + /* TODO: All acceptable number of faults before disabling */
> + replace_original_insn(current_uprobe, regs, cur->opcode);
> + /* Fall through and reset the current probe */
> + case UPROBE_SS_INLINE:
> + regs->eip = (unsigned long)cur->addr;
> + regs->eflags |= ucb->uprobe_old_eflags;
> + regs->eflags &= ~TF_MASK;
> + current_uprobe = NULL;
> + ret = 1;
> + spin_unlock_irqrestore(&uprobe_lock, ucb->flags);
> + preempt_enable_no_resched();
> + break;
> + case UPROBE_HIT_ACTIVE:
> + case UPROBE_SSDONE_INLINE:
> + case UPROBE_HIT_SSDONE:
> + if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
> + return 1;
> +
> + if (fixup_exception(regs))
> + return 1;
> + /*
> + * We must not allow the system page handler to continue while
> + * holding a lock, since page fault handler can sleep and
> + * reschedule it on different cpu. Hence return 1.
> + */
> + return 1;
> + break;
> + default:
> + break;
> + }
> + return ret;
> +}
> +
> +/*
> + * Wrapper routine to for handling exceptions.
> + */
> +int __kprobes uprobe_exceptions_notify(struct notifier_block *self,
> + unsigned long val, void *data)
> +{
> + struct die_args *args = (struct die_args *)data;
> + int ret = NOTIFY_DONE;
> +
> + if (args->regs->eflags & VM_MASK) {
> + /* We are in virtual-8086 mode. Return NOTIFY_DONE */
> + return ret;
> + }
> +
> + switch (val) {
> + case DIE_INT3:
> + if (uprobe_handler(args->regs))
> + ret = NOTIFY_STOP;
> + break;
> + case DIE_DEBUG:
> + if (post_uprobe_handler(args->regs))
> + ret = NOTIFY_STOP;
> + break;
> + case DIE_GPF:
> + case DIE_PAGE_FAULT:
> + if (current_uprobe &&
> + uprobe_fault_handler(args->regs, args->trapnr))
> + ret = NOTIFY_STOP;
> + break;
> + default:
> + break;
> + }
> + return ret;
> +}
> diff -puN arch/i386/kernel/kprobes.c~kprobes_userspace_probes-ss-out-of-line arch/i386/kernel/kprobes.c
> --- linux-2.6.17-rc3-mm1/arch/i386/kernel/kprobes.c~kprobes_userspace_probes-ss-out-of-line 2006-05-09 12:40:48.000000000 +0530
> +++ linux-2.6.17-rc3-mm1-prasanna/arch/i386/kernel/kprobes.c 2006-05-09 12:40:48.000000000 +0530
> @@ -139,7 +139,7 @@ retry:
> /*
> * returns non-zero if opcode modifies the interrupt flag.
> */
> -static int __kprobes is_IF_modifier(kprobe_opcode_t opcode)
> +int __kprobes is_IF_modifier(kprobe_opcode_t opcode)
> {
> switch (opcode) {
> case 0xfa: /* cli */
> @@ -649,7 +649,7 @@ int __kprobes kprobe_exceptions_notify(s
> int ret = NOTIFY_DONE;
>
> if (args->regs && user_mode(args->regs))
> - return ret;
> + return uprobe_exceptions_notify(self, val, data);
>
> switch (val) {
> case DIE_INT3:
> diff -puN arch/i386/mm/fault.c~kprobes_userspace_probes-ss-out-of-line arch/i386/mm/fault.c
> --- linux-2.6.17-rc3-mm1/arch/i386/mm/fault.c~kprobes_userspace_probes-ss-out-of-line 2006-05-09 12:40:48.000000000 +0530
> +++ linux-2.6.17-rc3-mm1-prasanna/arch/i386/mm/fault.c 2006-05-09 12:40:48.000000000 +0530
> @@ -104,8 +104,7 @@ void bust_spinlocks(int yes)
> *
> * This is slow, but is very rarely executed.
> */
> -static inline unsigned long get_segment_eip(struct pt_regs *regs,
> - unsigned long *eip_limit)
> +unsigned long get_segment_eip(struct pt_regs *regs, unsigned long *eip_limit)
> {
> unsigned long eip = regs->eip;
> unsigned seg = regs->xcs & 0xffff;
> diff -puN arch/i386/kernel/Makefile~kprobes_userspace_probes-ss-out-of-line arch/i386/kernel/Makefile
> --- linux-2.6.17-rc3-mm1/arch/i386/kernel/Makefile~kprobes_userspace_probes-ss-out-of-line 2006-05-09 12:40:48.000000000 +0530
> +++ linux-2.6.17-rc3-mm1-prasanna/arch/i386/kernel/Makefile 2006-05-09 12:40:48.000000000 +0530
> @@ -27,7 +27,7 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o
> obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> obj-$(CONFIG_X86_NUMAQ) += numaq.o
> obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
> -obj-$(CONFIG_KPROBES) += kprobes.o
> +obj-$(CONFIG_KPROBES) += kprobes.o uprobes.o
> obj-$(CONFIG_MODULES) += module.o
> obj-y += sysenter.o vsyscall.o
> obj-$(CONFIG_ACPI_SRAT) += srat.o
>
> _
next prev parent reply other threads:[~2006-05-10 0:47 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-09 6:55 [RFC] [PATCH 0/6] Kprobes: User-space probes support for i386 Prasanna S Panchamukhi
2006-05-09 6:59 ` [RFC] [PATCH 1/6] Kprobes: Allow/deny exclusive write access to inodes Prasanna S Panchamukhi
2006-05-09 7:01 ` [RFC] [PATCH 2/6] Kprobes: Get one pagetable entry Prasanna S Panchamukhi
2006-05-09 7:05 ` [RFC] [PATCH 3/6] Kprobes: New interfaces for user-space probes Prasanna S Panchamukhi
2006-05-09 7:09 ` [RFC] [PATCH 4/6] Kprobes: Insert probes on non-memory resident pages Prasanna S Panchamukhi
2006-05-09 7:12 ` [RFC] [PATCH 5/6] Kprobes: Single step the original instruction out-of-line Prasanna S Panchamukhi
2006-05-09 7:15 ` [RFC] [PATCH 6/6] Kprobes: Remove breakpoints from the copied pages Prasanna S Panchamukhi
2006-05-09 17:04 ` Hugh Dickins
2006-05-09 18:12 ` Frank Ch. Eigler
2006-05-10 8:42 ` Prasanna S Panchamukhi
2006-05-10 12:18 ` Prasanna S Panchamukhi
2006-05-10 19:16 ` Hugh Dickins
2006-05-09 9:38 ` [RFC] [PATCH 5/6] Kprobes: Single step the original instruction out-of-line Christoph Hellwig
2006-05-10 0:47 ` bibo,mao [this message]
2006-05-10 14:20 ` Richard J Moore
2006-05-09 9:34 ` [RFC] [PATCH 2/6] Kprobes: Get one pagetable entry Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44613812.1070100@linux.intel.com \
--to=bibo_mao@linux.intel.com \
--cc=ak@suse.de \
--cc=akpm@osdl.org \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=prasanna@in.ibm.com \
--cc=richardj_moore@uk.ibm.com \
--cc=suparna@in.ibm.com \
--cc=systemtap@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).