Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1204659 > unrolled thread
| Started by | David Long <dave.long@linaro.org> |
|---|---|
| First post | 2015-08-11 03:00 +0200 |
| Last post | 2015-08-13 06:30 +0200 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH v8 2/7] arm64: Add more test functions to insn.c David Long <dave.long@linaro.org> - 2015-08-11 03:00 +0200
Re: [PATCH v8 2/7] arm64: Add more test functions to insn.c Will Deacon <will.deacon@arm.com> - 2015-08-11 20:10 +0200
Re: [PATCH v8 2/7] arm64: Add more test functions to insn.c David Long <dave.long@linaro.org> - 2015-08-13 06:30 +0200
| From | David Long <dave.long@linaro.org> |
|---|---|
| Date | 2015-08-11 03:00 +0200 |
| Subject | [PATCH v8 2/7] arm64: Add more test functions to insn.c |
| Message-ID | <pW655-66O-11@gated-at.bofh.it> |
From: "David A. Long" <dave.long@linaro.org>
Certain instructions are hard to execute correctly out-of-line (as in
kprobes). Test functions are added to insn.[hc] to identify these. The
instructions include any that use PC-relative addressing, change the PC,
or change interrupt masking. For efficiency and simplicity test
functions are also added for small collections of related instructions.
Signed-off-by: David A. Long <dave.long@linaro.org>
---
arch/arm64/include/asm/insn.h | 18 ++++++++++++++++++
arch/arm64/kernel/insn.c | 28 ++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 30e50eb..66bfb21 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -223,8 +223,13 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
{ return (val); }
+__AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000)
+__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000)
__AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
__AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
+__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000)
+__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
+__AARCH64_INSN_FUNCS(exclusive, 0x3F000000, 0x08000000)
__AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000)
__AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000)
__AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000)
@@ -264,19 +269,29 @@ __AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000)
__AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000)
__AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000)
__AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000)
+__AARCH64_INSN_FUNCS(b_bl, 0x7C000000, 0x14000000)
+__AARCH64_INSN_FUNCS(cb, 0x7E000000, 0x34000000)
__AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000)
__AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000)
+__AARCH64_INSN_FUNCS(tb, 0x7E000000, 0x36000000)
__AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000)
__AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000)
+__AARCH64_INSN_FUNCS(b_bl_cb_tb, 0x5C000000, 0x14000000)
__AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000)
__AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
__AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
__AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003)
__AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000)
+__AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000)
__AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F)
__AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000)
__AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000)
+__AARCH64_INSN_FUNCS(br_blr, 0xFFDFFC1F, 0xD61F0000)
__AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000)
+__AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F)
+__AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000)
+__AARCH64_INSN_FUNCS(set_clr_daif, 0xFFFFF0DF, 0xD50340DF)
+__AARCH64_INSN_FUNCS(rd_wr_daif, 0xFFDFFFE0, 0xD51B4220)
#undef __AARCH64_INSN_FUNCS
@@ -286,6 +301,9 @@ bool aarch64_insn_is_branch_imm(u32 insn);
int aarch64_insn_read(void *addr, u32 *insnp);
int aarch64_insn_write(void *addr, u32 insn);
enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
+bool aarch64_insn_uses_literal(u32 insn);
+bool aarch64_insn_is_branch(u32 insn);
+bool aarch64_insn_is_daif_access(u32 insn);
u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn);
u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
u32 insn, u64 imm);
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index dd9671c..e532188 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -163,6 +163,34 @@ static bool __kprobes __aarch64_insn_hotpatch_safe(u32 insn)
aarch64_insn_is_nop(insn);
}
+bool __kprobes aarch64_insn_uses_literal(u32 insn)
+{
+ /* ldr/ldrsw (literal), prfm */
+
+ return aarch64_insn_is_ldr_lit(insn) ||
+ aarch64_insn_is_ldrsw_lit(insn) ||
+ aarch64_insn_is_adr_adrp(insn) ||
+ aarch64_insn_is_prfm_lit(insn);
+}
+
+bool __kprobes aarch64_insn_is_branch(u32 insn)
+{
+ /* b, bl, cb*, tb*, b.cond, br, blr */
+
+ return aarch64_insn_is_b_bl_cb_tb(insn) ||
+ aarch64_insn_is_br_blr(insn) ||
+ aarch64_insn_is_ret(insn) ||
+ aarch64_insn_is_bcond(insn);
+}
+
+bool __kprobes aarch64_insn_is_daif_access(u32 insn)
+{
+ /* msr daif, mrs daif, msr daifset, msr daifclr */
+
+ return aarch64_insn_is_rd_wr_daif(insn) ||
+ aarch64_insn_is_set_clr_daif(insn);
+}
+
/*
* ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
* Section B2.6.5 "Concurrent modification and execution of instructions":
--
1.8.1.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Will Deacon <will.deacon@arm.com> |
|---|---|
| Date | 2015-08-11 20:10 +0200 |
| Message-ID | <pWm9P-4tl-1@gated-at.bofh.it> |
| In reply to | #1204659 |
On Tue, Aug 11, 2015 at 01:52:39AM +0100, David Long wrote:
> From: "David A. Long" <dave.long@linaro.org>
>
> Certain instructions are hard to execute correctly out-of-line (as in
> kprobes). Test functions are added to insn.[hc] to identify these. The
> instructions include any that use PC-relative addressing, change the PC,
> or change interrupt masking. For efficiency and simplicity test
> functions are also added for small collections of related instructions.
>
> Signed-off-by: David A. Long <dave.long@linaro.org>
> ---
> arch/arm64/include/asm/insn.h | 18 ++++++++++++++++++
> arch/arm64/kernel/insn.c | 28 ++++++++++++++++++++++++++++
> 2 files changed, 46 insertions(+)
>
> diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
> index 30e50eb..66bfb21 100644
> --- a/arch/arm64/include/asm/insn.h
> +++ b/arch/arm64/include/asm/insn.h
> @@ -223,8 +223,13 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
> static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
> { return (val); }
>
> +__AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000)
> +__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000)
> __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
> __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
> +__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000)
> +__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
> +__AARCH64_INSN_FUNCS(exclusive, 0x3F000000, 0x08000000)
Hmm, so this class also pulls in load-acquire and store-release, which
we *should* be able to single-step, no? Maybe it's worth splitting this
category up (or at least changing aarch64_insn_is_exclusive to be more
permissive).
> __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000)
> __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000)
> __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000)
> @@ -264,19 +269,29 @@ __AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000)
> __AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000)
> __AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000)
> __AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000)
> +__AARCH64_INSN_FUNCS(b_bl, 0x7C000000, 0x14000000)
Why do we need this when we already have checks for b and bl?
> +__AARCH64_INSN_FUNCS(cb, 0x7E000000, 0x34000000)
Likewise for cbz and cbnz...
> __AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000)
> __AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000)
> +__AARCH64_INSN_FUNCS(tb, 0x7E000000, 0x36000000)
... there's a pattern here!
> __AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000)
> __AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000)
> +__AARCH64_INSN_FUNCS(b_bl_cb_tb, 0x5C000000, 0x14000000)
I must be missing something :)
> __AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000)
> __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
> __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
> __AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003)
> __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000)
> +__AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000)
> __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F)
> __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000)
> __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000)
> +__AARCH64_INSN_FUNCS(br_blr, 0xFFDFFC1F, 0xD61F0000)
> __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000)
> +__AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F)
> +__AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000)
> +__AARCH64_INSN_FUNCS(set_clr_daif, 0xFFFFF0DF, 0xD50340DF)
> +__AARCH64_INSN_FUNCS(rd_wr_daif, 0xFFDFFFE0, 0xD51B4220)
I think I'd rather have separate decoders to decode the register field
of an mrs/msr instruction than overload each encoding here.
Anyway, on the whole this looks pretty good, I'd just prefer not to build
compound instruction checks at the encoding level (even though it looks
like you did a good job on the values).
Will
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Long <dave.long@linaro.org> |
|---|---|
| Date | 2015-08-13 06:30 +0200 |
| Message-ID | <pWSjo-S5-3@gated-at.bofh.it> |
| In reply to | #1205346 |
On 08/11/15 14:00, Will Deacon wrote:
> On Tue, Aug 11, 2015 at 01:52:39AM +0100, David Long wrote:
>> From: "David A. Long" <dave.long@linaro.org>
>>
>> Certain instructions are hard to execute correctly out-of-line (as in
>> kprobes). Test functions are added to insn.[hc] to identify these. The
>> instructions include any that use PC-relative addressing, change the PC,
>> or change interrupt masking. For efficiency and simplicity test
>> functions are also added for small collections of related instructions.
>>
>> Signed-off-by: David A. Long <dave.long@linaro.org>
>> ---
>> arch/arm64/include/asm/insn.h | 18 ++++++++++++++++++
>> arch/arm64/kernel/insn.c | 28 ++++++++++++++++++++++++++++
>> 2 files changed, 46 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
>> index 30e50eb..66bfb21 100644
>> --- a/arch/arm64/include/asm/insn.h
>> +++ b/arch/arm64/include/asm/insn.h
>> @@ -223,8 +223,13 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
>> static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
>> { return (val); }
>>
>> +__AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000)
>> +__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000)
>> __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
>> __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
>> +__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000)
>> +__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
>> +__AARCH64_INSN_FUNCS(exclusive, 0x3F000000, 0x08000000)
>
> Hmm, so this class also pulls in load-acquire and store-release, which
> we *should* be able to single-step, no? Maybe it's worth splitting this
> category up (or at least changing aarch64_insn_is_exclusive to be more
> permissive).
I was not confident that this was the case. After reading the relevant
parts of the v8 ARM yet again I think I see your point.
>
>> __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000)
>> __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000)
>> __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000)
>> @@ -264,19 +269,29 @@ __AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000)
>> __AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000)
>> __AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000)
>> __AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000)
>> +__AARCH64_INSN_FUNCS(b_bl, 0x7C000000, 0x14000000)
>
> Why do we need this when we already have checks for b and bl?
I was trying to avoid doing multiple checks for different variants of
similar instructions.
>
>> +__AARCH64_INSN_FUNCS(cb, 0x7E000000, 0x34000000)
>
> Likewise for cbz and cbnz...
>
>> __AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000)
>> __AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000)
>> +__AARCH64_INSN_FUNCS(tb, 0x7E000000, 0x36000000)
>
> ... there's a pattern here!
>
^^
>> __AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000)
>> __AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000)
>> +__AARCH64_INSN_FUNCS(b_bl_cb_tb, 0x5C000000, 0x14000000)
>
> I must be missing something :)
^^
>
>> __AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000)
>> __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
>> __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
>> __AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003)
>> __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000)
>> +__AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000)
>> __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F)
>> __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000)
>> __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000)
>> +__AARCH64_INSN_FUNCS(br_blr, 0xFFDFFC1F, 0xD61F0000)
>> __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000)
>> +__AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F)
>> +__AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000)
>> +__AARCH64_INSN_FUNCS(set_clr_daif, 0xFFFFF0DF, 0xD50340DF)
>> +__AARCH64_INSN_FUNCS(rd_wr_daif, 0xFFDFFFE0, 0xD51B4220)
>
> I think I'd rather have separate decoders to decode the register field
> of an mrs/msr instruction than overload each encoding here.
>
> Anyway, on the whole this looks pretty good, I'd just prefer not to build
> compound instruction checks at the encoding level (even though it looks
> like you did a good job on the values).
>
OK, easy enough to just add to the if statements where these are getting
used. May be getting a little bloated looking there though.
-dl
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web