Skip to content

Commit 586e1ad

Browse files
committed
Merge branch 'for-next/insn' into for-next/core
* for-next/insn: arm64:uprobe fix the uprobe SWBP_INSN in big-endian arm64: insn: always inline hint generation arm64: insn: simplify insn group identification arm64: insn: always inline predicates arm64: insn: remove aarch64_insn_gen_prefetch()
2 parents a4aebff + 60f07e2 commit 586e1ad

File tree

4 files changed

+111
-214
lines changed

4 files changed

+111
-214
lines changed

arch/arm64/include/asm/insn.h

Lines changed: 109 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,6 @@
1313
#include <asm/insn-def.h>
1414

1515
#ifndef __ASSEMBLY__
16-
/*
17-
* ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
18-
* Section C3.1 "A64 instruction index by encoding":
19-
* AArch64 main encoding table
20-
* Bit position
21-
* 28 27 26 25 Encoding Group
22-
* 0 0 - - Unallocated
23-
* 1 0 0 - Data processing, immediate
24-
* 1 0 1 - Branch, exception generation and system instructions
25-
* - 1 - 0 Loads and stores
26-
* - 1 0 1 Data processing - register
27-
* 0 1 1 1 Data processing - SIMD and floating point
28-
* 1 1 1 1 Data processing - SIMD and floating point
29-
* "-" means "don't care"
30-
*/
31-
enum aarch64_insn_encoding_class {
32-
AARCH64_INSN_CLS_UNKNOWN, /* UNALLOCATED */
33-
AARCH64_INSN_CLS_SVE, /* SVE instructions */
34-
AARCH64_INSN_CLS_DP_IMM, /* Data processing - immediate */
35-
AARCH64_INSN_CLS_DP_REG, /* Data processing - register */
36-
AARCH64_INSN_CLS_DP_FPSIMD, /* Data processing - SIMD and FP */
37-
AARCH64_INSN_CLS_LDST, /* Loads and stores */
38-
AARCH64_INSN_CLS_BR_SYS, /* Branch, exception generation and
39-
* system instructions */
40-
};
4116

4217
enum aarch64_insn_hint_cr_op {
4318
AARCH64_INSN_HINT_NOP = 0x0 << 5,
@@ -326,6 +301,23 @@ static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
326301
return (val); \
327302
}
328303

304+
/*
305+
* ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
306+
* Section C3.1 "A64 instruction index by encoding":
307+
* AArch64 main encoding table
308+
* Bit position
309+
* 28 27 26 25 Encoding Group
310+
* 0 0 - - Unallocated
311+
* 1 0 0 - Data processing, immediate
312+
* 1 0 1 - Branch, exception generation and system instructions
313+
* - 1 - 0 Loads and stores
314+
* - 1 0 1 Data processing - register
315+
* 0 1 1 1 Data processing - SIMD and floating point
316+
* 1 1 1 1 Data processing - SIMD and floating point
317+
* "-" means "don't care"
318+
*/
319+
__AARCH64_INSN_FUNCS(class_branch_sys, 0x1c000000, 0x14000000)
320+
329321
__AARCH64_INSN_FUNCS(adr, 0x9F000000, 0x10000000)
330322
__AARCH64_INSN_FUNCS(adrp, 0x9F000000, 0x90000000)
331323
__AARCH64_INSN_FUNCS(prfm, 0x3FC00000, 0x39800000)
@@ -431,58 +423,122 @@ __AARCH64_INSN_FUNCS(pssbb, 0xFFFFFFFF, 0xD503349F)
431423

432424
#undef __AARCH64_INSN_FUNCS
433425

434-
bool aarch64_insn_is_steppable_hint(u32 insn);
435-
bool aarch64_insn_is_branch_imm(u32 insn);
426+
static __always_inline bool aarch64_insn_is_steppable_hint(u32 insn)
427+
{
428+
if (!aarch64_insn_is_hint(insn))
429+
return false;
430+
431+
switch (insn & 0xFE0) {
432+
case AARCH64_INSN_HINT_XPACLRI:
433+
case AARCH64_INSN_HINT_PACIA_1716:
434+
case AARCH64_INSN_HINT_PACIB_1716:
435+
case AARCH64_INSN_HINT_PACIAZ:
436+
case AARCH64_INSN_HINT_PACIASP:
437+
case AARCH64_INSN_HINT_PACIBZ:
438+
case AARCH64_INSN_HINT_PACIBSP:
439+
case AARCH64_INSN_HINT_BTI:
440+
case AARCH64_INSN_HINT_BTIC:
441+
case AARCH64_INSN_HINT_BTIJ:
442+
case AARCH64_INSN_HINT_BTIJC:
443+
case AARCH64_INSN_HINT_NOP:
444+
return true;
445+
default:
446+
return false;
447+
}
448+
}
449+
450+
static __always_inline bool aarch64_insn_is_branch(u32 insn)
451+
{
452+
/* b, bl, cb*, tb*, ret*, b.cond, br*, blr* */
453+
454+
return aarch64_insn_is_b(insn) ||
455+
aarch64_insn_is_bl(insn) ||
456+
aarch64_insn_is_cbz(insn) ||
457+
aarch64_insn_is_cbnz(insn) ||
458+
aarch64_insn_is_tbz(insn) ||
459+
aarch64_insn_is_tbnz(insn) ||
460+
aarch64_insn_is_ret(insn) ||
461+
aarch64_insn_is_ret_auth(insn) ||
462+
aarch64_insn_is_br(insn) ||
463+
aarch64_insn_is_br_auth(insn) ||
464+
aarch64_insn_is_blr(insn) ||
465+
aarch64_insn_is_blr_auth(insn) ||
466+
aarch64_insn_is_bcond(insn);
467+
}
436468

437-
static inline bool aarch64_insn_is_adr_adrp(u32 insn)
469+
static __always_inline bool aarch64_insn_is_branch_imm(u32 insn)
438470
{
439-
return aarch64_insn_is_adr(insn) || aarch64_insn_is_adrp(insn);
471+
return aarch64_insn_is_b(insn) ||
472+
aarch64_insn_is_bl(insn) ||
473+
aarch64_insn_is_tbz(insn) ||
474+
aarch64_insn_is_tbnz(insn) ||
475+
aarch64_insn_is_cbz(insn) ||
476+
aarch64_insn_is_cbnz(insn) ||
477+
aarch64_insn_is_bcond(insn);
440478
}
441479

442-
static inline bool aarch64_insn_is_dsb(u32 insn)
480+
static __always_inline bool aarch64_insn_is_adr_adrp(u32 insn)
443481
{
444-
return aarch64_insn_is_dsb_base(insn) || aarch64_insn_is_dsb_nxs(insn);
482+
return aarch64_insn_is_adr(insn) ||
483+
aarch64_insn_is_adrp(insn);
445484
}
446485

447-
static inline bool aarch64_insn_is_barrier(u32 insn)
486+
static __always_inline bool aarch64_insn_is_dsb(u32 insn)
448487
{
449-
return aarch64_insn_is_dmb(insn) || aarch64_insn_is_dsb(insn) ||
450-
aarch64_insn_is_isb(insn) || aarch64_insn_is_sb(insn) ||
451-
aarch64_insn_is_clrex(insn) || aarch64_insn_is_ssbb(insn) ||
488+
return aarch64_insn_is_dsb_base(insn) ||
489+
aarch64_insn_is_dsb_nxs(insn);
490+
}
491+
492+
static __always_inline bool aarch64_insn_is_barrier(u32 insn)
493+
{
494+
return aarch64_insn_is_dmb(insn) ||
495+
aarch64_insn_is_dsb(insn) ||
496+
aarch64_insn_is_isb(insn) ||
497+
aarch64_insn_is_sb(insn) ||
498+
aarch64_insn_is_clrex(insn) ||
499+
aarch64_insn_is_ssbb(insn) ||
452500
aarch64_insn_is_pssbb(insn);
453501
}
454502

455-
static inline bool aarch64_insn_is_store_single(u32 insn)
503+
static __always_inline bool aarch64_insn_is_store_single(u32 insn)
456504
{
457505
return aarch64_insn_is_store_imm(insn) ||
458506
aarch64_insn_is_store_pre(insn) ||
459507
aarch64_insn_is_store_post(insn);
460508
}
461509

462-
static inline bool aarch64_insn_is_store_pair(u32 insn)
510+
static __always_inline bool aarch64_insn_is_store_pair(u32 insn)
463511
{
464512
return aarch64_insn_is_stp(insn) ||
465513
aarch64_insn_is_stp_pre(insn) ||
466514
aarch64_insn_is_stp_post(insn);
467515
}
468516

469-
static inline bool aarch64_insn_is_load_single(u32 insn)
517+
static __always_inline bool aarch64_insn_is_load_single(u32 insn)
470518
{
471519
return aarch64_insn_is_load_imm(insn) ||
472520
aarch64_insn_is_load_pre(insn) ||
473521
aarch64_insn_is_load_post(insn);
474522
}
475523

476-
static inline bool aarch64_insn_is_load_pair(u32 insn)
524+
static __always_inline bool aarch64_insn_is_load_pair(u32 insn)
477525
{
478526
return aarch64_insn_is_ldp(insn) ||
479527
aarch64_insn_is_ldp_pre(insn) ||
480528
aarch64_insn_is_ldp_post(insn);
481529
}
482530

531+
static __always_inline bool aarch64_insn_uses_literal(u32 insn)
532+
{
533+
/* ldr/ldrsw (literal), prfm */
534+
535+
return aarch64_insn_is_ldr_lit(insn) ||
536+
aarch64_insn_is_ldrsw_lit(insn) ||
537+
aarch64_insn_is_adr_adrp(insn) ||
538+
aarch64_insn_is_prfm_lit(insn);
539+
}
540+
483541
enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
484-
bool aarch64_insn_uses_literal(u32 insn);
485-
bool aarch64_insn_is_branch(u32 insn);
486542
u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn);
487543
u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
488544
u32 insn, u64 imm);
@@ -496,8 +552,18 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
496552
enum aarch64_insn_branch_type type);
497553
u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
498554
enum aarch64_insn_condition cond);
499-
u32 aarch64_insn_gen_hint(enum aarch64_insn_hint_cr_op op);
500-
u32 aarch64_insn_gen_nop(void);
555+
556+
static __always_inline u32
557+
aarch64_insn_gen_hint(enum aarch64_insn_hint_cr_op op)
558+
{
559+
return aarch64_insn_get_hint_value() | op;
560+
}
561+
562+
static __always_inline u32 aarch64_insn_gen_nop(void)
563+
{
564+
return aarch64_insn_gen_hint(AARCH64_INSN_HINT_NOP);
565+
}
566+
501567
u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
502568
enum aarch64_insn_branch_type type);
503569
u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
@@ -580,10 +646,6 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
580646
enum aarch64_insn_register Rn,
581647
enum aarch64_insn_register Rd,
582648
u8 lsb);
583-
u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
584-
enum aarch64_insn_prfm_type type,
585-
enum aarch64_insn_prfm_target target,
586-
enum aarch64_insn_prfm_policy policy);
587649
#ifdef CONFIG_ARM64_LSE_ATOMICS
588650
u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
589651
enum aarch64_insn_register address,

arch/arm64/include/asm/uprobes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
#define MAX_UINSN_BYTES AARCH64_INSN_SIZE
1414

15-
#define UPROBE_SWBP_INSN BRK64_OPCODE_UPROBES
15+
#define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES)
1616
#define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE
1717
#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES
1818

arch/arm64/kernel/probes/decode-insn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static bool __kprobes aarch64_insn_is_steppable(u32 insn)
2424
* currently safe. Lastly, MSR instructions can do any number of nasty
2525
* things we can't handle during single-stepping.
2626
*/
27-
if (aarch64_get_insn_class(insn) == AARCH64_INSN_CLS_BR_SYS) {
27+
if (aarch64_insn_is_class_branch_sys(insn)) {
2828
if (aarch64_insn_is_branch(insn) ||
2929
aarch64_insn_is_msr_imm(insn) ||
3030
aarch64_insn_is_msr_reg(insn) ||

0 commit comments

Comments
 (0)