lkml.org 
[lkml]   [2020]   [Sep]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 10/72] x86/insn: Add insn_get_modrm_reg_off()
    Date
    From: Joerg Roedel <jroedel@suse.de>

    Add a function to the instruction decoder which returns the pt_regs
    offset of the register specified in the reg field of the modrm byte.

    Signed-off-by: Joerg Roedel <jroedel@suse.de>
    Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
    ---
    arch/x86/include/asm/insn-eval.h | 1 +
    arch/x86/lib/insn-eval.c | 23 +++++++++++++++++++++++
    2 files changed, 24 insertions(+)

    diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h
    index 392b4fe377f9..f748f57f1491 100644
    --- a/arch/x86/include/asm/insn-eval.h
    +++ b/arch/x86/include/asm/insn-eval.h
    @@ -17,6 +17,7 @@

    void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs);
    int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs);
    +int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs);
    unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx);
    int insn_get_code_seg_params(struct pt_regs *regs);
    int insn_fetch_from_user(struct pt_regs *regs,
    diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
    index 2323c85132cf..f20942ce76c6 100644
    --- a/arch/x86/lib/insn-eval.c
    +++ b/arch/x86/lib/insn-eval.c
    @@ -20,6 +20,7 @@

    enum reg_type {
    REG_TYPE_RM = 0,
    + REG_TYPE_REG,
    REG_TYPE_INDEX,
    REG_TYPE_BASE,
    };
    @@ -439,6 +440,13 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
    regno += 8;
    break;

    + case REG_TYPE_REG:
    + regno = X86_MODRM_REG(insn->modrm.value);
    +
    + if (X86_REX_R(insn->rex_prefix.value))
    + regno += 8;
    + break;
    +
    case REG_TYPE_INDEX:
    regno = X86_SIB_INDEX(insn->sib.value);
    if (X86_REX_X(insn->rex_prefix.value))
    @@ -807,6 +815,21 @@ int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs)
    return get_reg_offset(insn, regs, REG_TYPE_RM);
    }

    +/**
    + * insn_get_modrm_reg_off() - Obtain register in reg part of the ModRM byte
    + * @insn: Instruction containing the ModRM byte
    + * @regs: Register values as seen when entering kernel mode
    + *
    + * Returns:
    + *
    + * The register indicated by the reg part of the ModRM byte. The
    + * register is obtained as an offset from the base of pt_regs.
    + */
    +int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs)
    +{
    + return get_reg_offset(insn, regs, REG_TYPE_REG);
    +}
    +
    /**
    * get_seg_base_limit() - obtain base address and limit of a segment
    * @insn: Instruction. Must be valid.
    --
    2.28.0
    \
     
     \ /
      Last update: 2020-09-07 19:33    [W:3.312 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site