Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933477AbdCHAm2 (ORCPT ); Tue, 7 Mar 2017 19:42:28 -0500 Received: from mga02.intel.com ([134.134.136.20]:3220 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933360AbdCHAmX (ORCPT ); Tue, 7 Mar 2017 19:42:23 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,261,1486454400"; d="scan'208";a="1105982572" From: Ricardo Neri To: Ingo Molnar , Thomas Gleixner , "H. Peter Anvin" , Andy Lutomirski , Borislav Petkov Cc: Peter Zijlstra , Andrew Morton , Brian Gerst , Chris Metcalf , Dave Hansen , Paolo Bonzini , Liang Z Li , Masami Hiramatsu , Huang Rui , Jiri Slaby , Jonathan Corbet , "Michael S. Tsirkin" , Paul Gortmaker , Vlastimil Babka , Chen Yucong , Alexandre Julliard , Stas Sergeev , Fenghua Yu , "Ravi V. Shankar" , Shuah Khan , linux-kernel@vger.kernel.org, x86@kernel.org, linux-msdos@vger.kernel.org, wine-devel@winehq.org, Ricardo Neri , Adam Buchbinder , Colin Ian King , Lorenzo Stoakes , Qiaowei Ren , Arnaldo Carvalho de Melo , Adrian Hunter , Kees Cook , Thomas Garnier , Dmitry Vyukov Subject: [v6 PATCH 05/21] x86/insn-eval: Add utility functions to get register offsets Date: Tue, 7 Mar 2017 16:32:38 -0800 Message-Id: <20170308003254.27833-6-ricardo.neri-calderon@linux.intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170308003254.27833-1-ricardo.neri-calderon@linux.intel.com> References: <20170308003254.27833-1-ricardo.neri-calderon@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4440 Lines: 107 The function insn_get_reg_offset takes as argument an enumeration that indicates the type of offset that is returned: the R/M part of the ModRM byte, the index of the SIB byte or the base of the SIB byte. Callers of this function would need the definition of such enumeration. This is not needed. Instead, helper functions can be defined for this purpose can be added. These functions are useful in cases when, for instance, the caller needs to decide whether the operand is a register or a memory location by looking at the mod part of the ModRM byte. Cc: Dave Hansen Cc: Adam Buchbinder Cc: Colin Ian King Cc: Lorenzo Stoakes Cc: Qiaowei Ren Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Adrian Hunter Cc: Kees Cook Cc: Thomas Garnier Cc: Peter Zijlstra Cc: Borislav Petkov Cc: Dmitry Vyukov Cc: Ravi V. Shankar Cc: x86@kernel.org Signed-off-by: Ricardo Neri --- arch/x86/include/asm/insn-eval.h | 3 +++ arch/x86/lib/insn-eval.c | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h index 5cab1b1..754211b 100644 --- a/arch/x86/include/asm/insn-eval.h +++ b/arch/x86/include/asm/insn-eval.h @@ -12,5 +12,8 @@ #include void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs); +int insn_get_reg_offset_modrm_rm(struct insn *insn, struct pt_regs *regs); +int insn_get_reg_offset_sib_base(struct insn *insn, struct pt_regs *regs); +int insn_get_reg_offset_sib_base(struct insn *insn, struct pt_regs *regs); #endif /* _ASM_X86_INSN_EVAL_H */ diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c index 23cf010..78df1c9 100644 --- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -98,6 +98,57 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs, return regoff[regno]; } +/** + * insn_get_reg_offset_modrm_rm - Obtain register in r/m part of ModRM byte + * @insn: Instruction structure containing the ModRM byte + * @regs: Set of registers indicated by the ModRM byte + * + * Obtain the register indicated by the r/m part of the ModRM byte. The + * register is obtained as an offset from the base of pt_regs. In specific + * cases, the returned value can be -EDOM to indicate that the particular value + * of ModRM does not refer to a register. + * + * Return: Register indicated by r/m, as an offset within struct pt_regs + */ +int insn_get_reg_offset_modrm_rm(struct insn *insn, struct pt_regs *regs) +{ + return get_reg_offset(insn, regs, REG_TYPE_RM); +} + +/** + * insn_get_reg_offset_sib_base - Obtain register in base part of SiB byte + * @insn: Instruction structure containing the SiB byte + * @regs: Set of registers indicated by the SiB byte + * + * Obtain the register indicated by the base part of the SiB byte. The + * register is obtained as an offset from the base of pt_regs. In specific + * cases, the returned value can be -EDOM to indicate that the particular value + * of SiB does not refer to a register. + * + * Return: Register indicated by SiB's base, as an offset within struct pt_regs + */ +int insn_get_reg_offset_sib_base(struct insn *insn, struct pt_regs *regs) +{ + return get_reg_offset(insn, regs, REG_TYPE_BASE); +} + +/** + * insn_get_reg_offset_sib_index - Obtain register in index part of SiB byte + * @insn: Instruction structure containing the SiB byte + * @regs: Set of registers indicated by the SiB byte + * + * Obtain the register indicated by the index part of the SiB byte. The + * register is obtained as an offset from the index of pt_regs. In specific + * cases, the returned value can be -EDOM to indicate that the particular value + * of SiB does not refer to a register. + * + * Return: Register indicated by SiB's base, as an offset within struct pt_regs + */ +int insn_get_reg_offset_sib_index(struct insn *insn, struct pt_regs *regs) +{ + return get_reg_offset(insn, regs, REG_TYPE_INDEX); +} + /* * return the address being referenced be instruction * for rm=3 returning the content of the rm reg -- 2.9.3