lkml.org 
[lkml]   [2009]   [Apr]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC][PROTO][PATCH -tip 7/7] kprobes: x86: check specified probe can be optimized
    Introduce can_optimize() function for ensuring that user specified probe
    address can be jump optimized by decoding instructions.
    This function decodes whole of a function in which probe is inserted, and
    checks following condition:
    - There is no indirect jump instruction, because it will jumps into
    the address range which is replaced by jump oprand.
    - There is no jump/loop instruction which jumps into the address range
    which is replaced by jump oprand.

    Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
    ---

    arch/x86/kernel/kprobes.c | 75 +++++++++++++++++++++++++++++++++++++++++++++
    1 files changed, 75 insertions(+), 0 deletions(-)


    diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
    index 5635e02..1386e34 100644
    --- a/arch/x86/kernel/kprobes.c
    +++ b/arch/x86/kernel/kprobes.c
    @@ -1253,6 +1253,78 @@ static int __kprobes prepare_copied_insn(u8 *buf, struct optimized_kprobe *op)
    return len;
    }

    +/* Dummy buffers for lookup_symbol_attrs */
    +static char __dummy_buf[KSYM_NAME_LEN];
    +
    +/* Check whether insn is indirect jump */
    +static int insn_is_indirect_jump(struct insn *insn)
    +{
    + return (OPCODE1(insn) == 0xff || OPCODE1(insn) == 0xea);
    +}
    +
    +/* Check whether insn jumps into specified address range */
    +static int insn_jump_into_range(struct insn *insn, unsigned long start, int len)
    +{
    + unsigned long target = 0;
    + switch (OPCODE1(insn)) {
    + case 0xe0: /* loopne */
    + case 0xe1: /* loope */
    + case 0xe2: /* loop */
    + case 0xe3: /* jcxz */
    + case 0xe9: /* near relative jump */
    + case 0xeb: /* short relative jump */
    + break;
    + case 0x0f:
    + if ((OPCODE2(insn) & 0xf0) == 0x80) /* jcc near */
    + break;
    + return 0;
    + default:
    + if ((OPCODE1(insn) & 0xf0) == 0x70) /* jcc short */
    + break;
    + return 0;
    + }
    + target = (unsigned long)insn->next_byte + insn->immediate.value;
    + return (start <= target && target <= start + len);
    +}
    +
    +/* Decode whole function to ensure any instructions don't jump into target */
    +static int __kprobes can_optimize(unsigned long paddr)
    +{
    + int ret;
    + unsigned long addr, size = 0, offset = 0;
    + struct insn insn;
    + kprobe_opcode_t buf[MAX_INSN_SIZE];
    +
    + /* Lookup symbol including addr */
    + if (!kallsyms_lookup(paddr, &size, &offset, NULL, __dummy_buf))
    + return 0;
    +
    + /* Decode instructions */
    + addr = paddr - offset;
    + while (addr < paddr - offset + size) { /* Decode until function end */
    + insn_init_kernel(&insn, (void *)addr);
    + insn_get_opcode(&insn);
    + if (OPCODE1(&insn) == BREAKPOINT_INSTRUCTION) {
    + ret = recover_probed_instruction(buf, addr);
    + if (ret)
    + return 0;
    + insn_init_kernel(&insn, buf);
    + }
    + insn_get_length(&insn);
    + /* Recover address */
    + insn.kaddr = (void *)addr;
    + insn.next_byte = (void *)(addr + insn.length);
    + /* Check any instructions don't jump into target */
    + if (insn_is_indirect_jump(&insn) ||
    + insn_jump_into_range(&insn, addr + INT3_SIZE,
    + RELATIVE_ADDR_SIZE))
    + return 0;
    + addr += insn.length;
    + }
    +
    + return 1;
    +}
    +
    int arch_optimized_kprobe_address(struct optimized_kprobe *op,
    unsigned long addr)
    {
    @@ -1269,6 +1341,9 @@ int __kprobes arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
    u8 *buf;
    int ret, i;

    + if (!can_optimize((unsigned long)op->kp.addr))
    + return -EINVAL;
    +
    op->optinsn.insn = get_optinsn_slot();
    if (!op->optinsn.insn)
    return -ENOMEM;
    --
    Masami Hiramatsu
    Software Engineer
    Hitachi Computer Products (America) Inc.
    Software Solutions Division

    e-mail: mhiramat@redhat.com



    \
     
     \ /
      Last update: 2009-04-06 23:45    [W:0.027 / U:1.492 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site