mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jungseok Lee <jungseoklee85@gmail.com>
To: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: catalin.marinas@arm.com, will.deacon@arm.com,
	rostedt@goodmis.org, broonie@kernel.org, david.griego@linaro.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 4/6] arm64: insn: add instruction decoders for ldp/stp and add/sub
Date: Tue, 10 Nov 2015 22:40:41 +0900	[thread overview]
Message-ID: <999DB062-D4C8-4050-ADF7-9C6CEEC0BF73@gmail.com> (raw)
In-Reply-To: <1446792285-1154-5-git-send-email-takahiro.akashi@linaro.org>

On Nov 6, 2015, at 3:44 PM, AKASHI Takahiro wrote:
> A function prologue analyzer is a requisite for implementing stack tracer
> and getting better views of stack usages on arm64.
> To implement a function prologue analyzer, we have to be able to decode,
> at least, stp, add, sub and mov instructions.
> 
> This patch adds decoders for those instructions, that are used solely
> by stack tracer for now, but generic enough for other uses.
> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> ---
> arch/arm64/include/asm/insn.h |   18 ++++++++
> arch/arm64/kernel/insn.c      |  102 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 120 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
> index 30e50eb..8d5c538 100644
> --- a/arch/arm64/include/asm/insn.h
> +++ b/arch/arm64/include/asm/insn.h
> @@ -165,6 +165,8 @@ enum aarch64_insn_ldst_type {
> 	AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX,
> 	AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX,
> 	AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX,
> +	AARCH64_INSN_LDST_LOAD_PAIR,
> +	AARCH64_INSN_LDST_STORE_PAIR,
> };
> 
> enum aarch64_insn_adsb_type {
> @@ -225,6 +227,8 @@ static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
> 
> __AARCH64_INSN_FUNCS(str_reg,	0x3FE0EC00, 0x38206800)
> __AARCH64_INSN_FUNCS(ldr_reg,	0x3FE0EC00, 0x38606800)
> +__AARCH64_INSN_FUNCS(stp,	0x7FC00000, 0x29000000)
> +__AARCH64_INSN_FUNCS(ldp,	0x7FC00000, 0x29400000)
> __AARCH64_INSN_FUNCS(stp_post,	0x7FC00000, 0x28800000)
> __AARCH64_INSN_FUNCS(ldp_post,	0x7FC00000, 0x28C00000)
> __AARCH64_INSN_FUNCS(stp_pre,	0x7FC00000, 0x29800000)
> @@ -277,6 +281,7 @@ __AARCH64_INSN_FUNCS(hint,	0xFFFFF01F, 0xD503201F)
> __AARCH64_INSN_FUNCS(br,	0xFFFFFC1F, 0xD61F0000)
> __AARCH64_INSN_FUNCS(blr,	0xFFFFFC1F, 0xD63F0000)
> __AARCH64_INSN_FUNCS(ret,	0xFFFFFC1F, 0xD65F0000)
> +__AARCH64_INSN_FUNCS(eret,	0xFFFFFFFF, 0xD69F00E0)

According to C4.2.7, the third argument looks like 0xD69F03E0. Rn field is 11111
in case of eret.

Best Regards
Jungseok Lee

> #undef	__AARCH64_INSN_FUNCS
> 
> @@ -370,6 +375,19 @@ bool aarch32_insn_is_wide(u32 insn);
> u32 aarch32_insn_extract_reg_num(u32 insn, int offset);
> u32 aarch32_insn_mcr_extract_opc2(u32 insn);
> u32 aarch32_insn_mcr_extract_crm(u32 insn);
> +int aarch64_insn_decode_add_sub_imm(u32 insn,
> +				    enum aarch64_insn_register *dst,
> +				    enum aarch64_insn_register *src,
> +				    int *imm,
> +				    enum aarch64_insn_variant *variant,
> +				    enum aarch64_insn_adsb_type *type);
> +int aarch64_insn_decode_load_store_pair(u32 insn,
> +					enum aarch64_insn_register *reg1,
> +					enum aarch64_insn_register *reg2,
> +					enum aarch64_insn_register *base,
> +					int *offset,
> +					enum aarch64_insn_variant *variant,
> +					enum aarch64_insn_ldst_type *type);
> #endif /* __ASSEMBLY__ */
> 
> #endif	/* __ASM_INSN_H */
> diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
> index c08b9ad..b56a66c 100644
> --- a/arch/arm64/kernel/insn.c
> +++ b/arch/arm64/kernel/insn.c
> @@ -33,6 +33,7 @@
> #include <asm/insn.h>
> 
> #define AARCH64_INSN_SF_BIT	BIT(31)
> +#define AARCH64_INSN_S_BIT	BIT(29)
> #define AARCH64_INSN_N_BIT	BIT(22)
> 
> static int aarch64_insn_encoding_class[] = {
> @@ -1141,3 +1142,104 @@ u32 aarch32_insn_mcr_extract_crm(u32 insn)
> {
> 	return insn & CRM_MASK;
> }
> +
> +enum aarch64_insn_register aarch64_insn_extract_reg_num(u32 insn,
> +				enum aarch64_insn_register_type type)
> +{
> +	int shift;
> +
> +	switch (type) {
> +	case AARCH64_INSN_REGTYPE_RT:
> +	case AARCH64_INSN_REGTYPE_RD:
> +		shift = 0;
> +		break;
> +	case AARCH64_INSN_REGTYPE_RN:
> +		shift = 5;
> +		break;
> +	case AARCH64_INSN_REGTYPE_RT2:
> +	case AARCH64_INSN_REGTYPE_RA:
> +		shift = 10;
> +		break;
> +	case AARCH64_INSN_REGTYPE_RM:
> +		shift = 16;
> +		break;
> +	default:
> +		pr_err("%s: unknown register type decoding %d\n", __func__,
> +		       type);
> +		return ~0L;
> +	}
> +
> +	return (insn & (GENMASK(4, 0) << shift)) >> shift;
> +}
> +
> +int aarch64_insn_decode_add_sub_imm(u32 insn,
> +				    enum aarch64_insn_register *dst,
> +				    enum aarch64_insn_register *src,
> +				    int *imm,
> +				    enum aarch64_insn_variant *variant,
> +				    enum aarch64_insn_adsb_type *type)
> +{
> +	if (aarch64_insn_is_add_imm(insn))
> +		*type =	((insn) & AARCH64_INSN_S_BIT) ?
> +				AARCH64_INSN_ADSB_ADD_SETFLAGS :
> +				AARCH64_INSN_ADSB_ADD;
> +	else if (aarch64_insn_is_sub_imm(insn))
> +		*type =	((insn) & AARCH64_INSN_S_BIT) ?
> +				AARCH64_INSN_ADSB_SUB_SETFLAGS :
> +				AARCH64_INSN_ADSB_SUB;
> +	else
> +		return 0;
> +
> +	*variant = (insn & AARCH64_INSN_SF_BIT) ? AARCH64_INSN_VARIANT_64BIT :
> +					AARCH64_INSN_VARIANT_32BIT;
> +
> +	*dst = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RD);
> +
> +	*src = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RN);
> +
> +	/* TODO: ignore shilft field[23:22] */
> +	*imm = (int)aarch64_insn_decode_immediate(AARCH64_INSN_IMM_12, insn);
> +
> +	return 1;
> +}
> +
> +int aarch64_insn_decode_load_store_pair(u32 insn,
> +					enum aarch64_insn_register *reg1,
> +					enum aarch64_insn_register *reg2,
> +					enum aarch64_insn_register *base,
> +					int *offset,
> +					enum aarch64_insn_variant *variant,
> +					enum aarch64_insn_ldst_type *type)
> +{
> +	int imm;
> +
> +	if (aarch64_insn_is_stp(insn))
> +		*type = AARCH64_INSN_LDST_STORE_PAIR;
> +	else if (aarch64_insn_is_stp_post(insn))
> +		*type = AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX;
> +	else if (aarch64_insn_is_stp_pre(insn))
> +		*type = AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX;
> +	else if (aarch64_insn_is_ldp(insn))
> +		*type = AARCH64_INSN_LDST_LOAD_PAIR;
> +	else if (aarch64_insn_is_ldp_post(insn))
> +		*type = AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX;
> +	else if (aarch64_insn_is_ldp_pre(insn))
> +		*type = AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX;
> +	else
> +		return 0;
> +
> +	*variant = (insn & AARCH64_INSN_S_BIT) ? AARCH64_INSN_VARIANT_64BIT :
> +				AARCH64_INSN_VARIANT_32BIT;
> +
> +	*reg1 = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RT);
> +
> +	*reg2 = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RT2);
> +
> +	*base = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RN);
> +
> +	imm = (int)aarch64_insn_decode_immediate(AARCH64_INSN_IMM_7, insn);
> +	asm("sbfm %0, %0, 0, 6" : "+r" (imm));
> +	*offset = imm * 8;
> +
> +	return 1;
> +}
> -- 
> 1.7.9.5
> 


  reply	other threads:[~2015-11-10 13:40 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-06  6:44 [PATCH v5 0/6] arm64: ftrace: fix incorrect output from stack tracer AKASHI Takahiro
2015-11-06  6:44 ` [PATCH v5 1/6] arm64: ftrace: modify a stack frame in a safe way AKASHI Takahiro
2015-11-06  6:44 ` [PATCH v5 2/6] arm64: ftrace: fix a stack tracer's output under function graph tracer AKASHI Takahiro
2015-11-09 14:04   ` Jungseok Lee
2015-11-10  2:42     ` AKASHI Takahiro
2015-11-13 15:01       ` Jungseok Lee
2015-11-16  9:23         ` AKASHI Takahiro
2015-11-06  6:44 ` [PATCH v5 3/6] ftrace: allow arch-specific stack tracer AKASHI Takahiro
2015-11-06 13:39   ` Steven Rostedt
2015-11-06  6:44 ` [PATCH v5 4/6] arm64: insn: add instruction decoders for ldp/stp and add/sub AKASHI Takahiro
2015-11-10 13:40   ` Jungseok Lee [this message]
2015-11-11  4:54     ` AKASHI Takahiro
2015-11-06  6:44 ` [PATCH v5 5/6] arm64: ftrace: add arch-specific stack tracer AKASHI Takahiro
2015-11-10 14:05   ` Jungseok Lee
2015-11-11  5:03     ` AKASHI Takahiro
2015-11-11 22:56       ` Jungseok Lee
2015-11-06  6:44 ` [PATCH v5 6/6] arm64: ftrace: add a test of function prologue analyzer AKASHI Takahiro
2015-11-09 14:24 ` [PATCH v5 0/6] arm64: ftrace: fix incorrect output from stack tracer Jungseok Lee
2015-11-10  2:58   ` AKASHI Takahiro
2015-11-10 13:32     ` Jungseok Lee

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=999DB062-D4C8-4050-ADF7-9C6CEEC0BF73@gmail.com \
    --to=jungseoklee85@gmail.com \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=david.griego@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=takahiro.akashi@linaro.org \
    --cc=will.deacon@arm.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

all inboxes | Powered by JetHome®