Skip to content

Commit 181a126

Browse files
committed
Merge branch 'for-next/insn' into for-next/core
Refactoring of our instruction decoding routines and addition of some missing encodings. * for-next/insn: arm64: insn: avoid circular include dependency arm64: insn: move AARCH64_INSN_SIZE into <asm/insn.h> arm64: insn: decouple patching from insn code arm64: insn: Add load/store decoding helpers arm64: insn: Add some opcodes to instruction decoder arm64: insn: Add barrier encodings arm64: insn: Add SVE instruction class arm64: Move instruction encoder/decoder under lib/ arm64: Move aarch32 condition check functions arm64: Move patching utilities out of instruction encoding/decoding
2 parents 6cf61e0 + 69bb058 commit 181a126

17 files changed

Lines changed: 358 additions & 265 deletions

File tree

arch/arm64/include/asm/alternative-macros.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
#define __ASM_ALTERNATIVE_MACROS_H
44

55
#include <asm/cpucaps.h>
6+
#include <asm/insn-def.h>
67

78
#define ARM64_CB_PATCH ARM64_NCAPS
89

9-
/* A64 instructions are always 32 bits. */
10-
#define AARCH64_INSN_SIZE 4
11-
1210
#ifndef __ASSEMBLY__
1311

1412
#include <linux/stringify.h>

arch/arm64/include/asm/insn-def.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#ifndef __ASM_INSN_DEF_H
4+
#define __ASM_INSN_DEF_H
5+
6+
/* A64 instructions are always 32 bits. */
7+
#define AARCH64_INSN_SIZE 4
8+
9+
#endif /* __ASM_INSN_DEF_H */

arch/arm64/include/asm/insn.h

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <linux/build_bug.h>
1111
#include <linux/types.h>
1212

13-
#include <asm/alternative.h>
13+
#include <asm/insn-def.h>
1414

1515
#ifndef __ASSEMBLY__
1616
/*
@@ -30,6 +30,7 @@
3030
*/
3131
enum aarch64_insn_encoding_class {
3232
AARCH64_INSN_CLS_UNKNOWN, /* UNALLOCATED */
33+
AARCH64_INSN_CLS_SVE, /* SVE instructions */
3334
AARCH64_INSN_CLS_DP_IMM, /* Data processing - immediate */
3435
AARCH64_INSN_CLS_DP_REG, /* Data processing - register */
3536
AARCH64_INSN_CLS_DP_FPSIMD, /* Data processing - SIMD and FP */
@@ -294,6 +295,12 @@ __AARCH64_INSN_FUNCS(adr, 0x9F000000, 0x10000000)
294295
__AARCH64_INSN_FUNCS(adrp, 0x9F000000, 0x90000000)
295296
__AARCH64_INSN_FUNCS(prfm, 0x3FC00000, 0x39800000)
296297
__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000)
298+
__AARCH64_INSN_FUNCS(store_imm, 0x3FC00000, 0x39000000)
299+
__AARCH64_INSN_FUNCS(load_imm, 0x3FC00000, 0x39400000)
300+
__AARCH64_INSN_FUNCS(store_pre, 0x3FE00C00, 0x38000C00)
301+
__AARCH64_INSN_FUNCS(load_pre, 0x3FE00C00, 0x38400C00)
302+
__AARCH64_INSN_FUNCS(store_post, 0x3FE00C00, 0x38000400)
303+
__AARCH64_INSN_FUNCS(load_post, 0x3FE00C00, 0x38400400)
297304
__AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
298305
__AARCH64_INSN_FUNCS(ldadd, 0x3F20FC00, 0x38200000)
299306
__AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
@@ -302,6 +309,8 @@ __AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
302309
__AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000)
303310
__AARCH64_INSN_FUNCS(load_ex, 0x3F400000, 0x08400000)
304311
__AARCH64_INSN_FUNCS(store_ex, 0x3F400000, 0x08000000)
312+
__AARCH64_INSN_FUNCS(stp, 0x7FC00000, 0x29000000)
313+
__AARCH64_INSN_FUNCS(ldp, 0x7FC00000, 0x29400000)
305314
__AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000)
306315
__AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000)
307316
__AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000)
@@ -334,6 +343,7 @@ __AARCH64_INSN_FUNCS(rev64, 0x7FFFFC00, 0x5AC00C00)
334343
__AARCH64_INSN_FUNCS(and, 0x7F200000, 0x0A000000)
335344
__AARCH64_INSN_FUNCS(bic, 0x7F200000, 0x0A200000)
336345
__AARCH64_INSN_FUNCS(orr, 0x7F200000, 0x2A000000)
346+
__AARCH64_INSN_FUNCS(mov_reg, 0x7FE0FFE0, 0x2A0003E0)
337347
__AARCH64_INSN_FUNCS(orn, 0x7F200000, 0x2A200000)
338348
__AARCH64_INSN_FUNCS(eor, 0x7F200000, 0x4A000000)
339349
__AARCH64_INSN_FUNCS(eon, 0x7F200000, 0x4A200000)
@@ -368,6 +378,14 @@ __AARCH64_INSN_FUNCS(eret_auth, 0xFFFFFBFF, 0xD69F0BFF)
368378
__AARCH64_INSN_FUNCS(mrs, 0xFFF00000, 0xD5300000)
369379
__AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F)
370380
__AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000)
381+
__AARCH64_INSN_FUNCS(dmb, 0xFFFFF0FF, 0xD50330BF)
382+
__AARCH64_INSN_FUNCS(dsb_base, 0xFFFFF0FF, 0xD503309F)
383+
__AARCH64_INSN_FUNCS(dsb_nxs, 0xFFFFF3FF, 0xD503323F)
384+
__AARCH64_INSN_FUNCS(isb, 0xFFFFF0FF, 0xD50330DF)
385+
__AARCH64_INSN_FUNCS(sb, 0xFFFFFFFF, 0xD50330FF)
386+
__AARCH64_INSN_FUNCS(clrex, 0xFFFFF0FF, 0xD503305F)
387+
__AARCH64_INSN_FUNCS(ssbb, 0xFFFFFFFF, 0xD503309F)
388+
__AARCH64_INSN_FUNCS(pssbb, 0xFFFFFFFF, 0xD503349F)
371389

372390
#undef __AARCH64_INSN_FUNCS
373391

@@ -379,8 +397,47 @@ static inline bool aarch64_insn_is_adr_adrp(u32 insn)
379397
return aarch64_insn_is_adr(insn) || aarch64_insn_is_adrp(insn);
380398
}
381399

382-
int aarch64_insn_read(void *addr, u32 *insnp);
383-
int aarch64_insn_write(void *addr, u32 insn);
400+
static inline bool aarch64_insn_is_dsb(u32 insn)
401+
{
402+
return aarch64_insn_is_dsb_base(insn) || aarch64_insn_is_dsb_nxs(insn);
403+
}
404+
405+
static inline bool aarch64_insn_is_barrier(u32 insn)
406+
{
407+
return aarch64_insn_is_dmb(insn) || aarch64_insn_is_dsb(insn) ||
408+
aarch64_insn_is_isb(insn) || aarch64_insn_is_sb(insn) ||
409+
aarch64_insn_is_clrex(insn) || aarch64_insn_is_ssbb(insn) ||
410+
aarch64_insn_is_pssbb(insn);
411+
}
412+
413+
static inline bool aarch64_insn_is_store_single(u32 insn)
414+
{
415+
return aarch64_insn_is_store_imm(insn) ||
416+
aarch64_insn_is_store_pre(insn) ||
417+
aarch64_insn_is_store_post(insn);
418+
}
419+
420+
static inline bool aarch64_insn_is_store_pair(u32 insn)
421+
{
422+
return aarch64_insn_is_stp(insn) ||
423+
aarch64_insn_is_stp_pre(insn) ||
424+
aarch64_insn_is_stp_post(insn);
425+
}
426+
427+
static inline bool aarch64_insn_is_load_single(u32 insn)
428+
{
429+
return aarch64_insn_is_load_imm(insn) ||
430+
aarch64_insn_is_load_pre(insn) ||
431+
aarch64_insn_is_load_post(insn);
432+
}
433+
434+
static inline bool aarch64_insn_is_load_pair(u32 insn)
435+
{
436+
return aarch64_insn_is_ldp(insn) ||
437+
aarch64_insn_is_ldp_pre(insn) ||
438+
aarch64_insn_is_ldp_post(insn);
439+
}
440+
384441
enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
385442
bool aarch64_insn_uses_literal(u32 insn);
386443
bool aarch64_insn_is_branch(u32 insn);
@@ -487,9 +544,6 @@ u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
487544
s32 aarch64_get_branch_offset(u32 insn);
488545
u32 aarch64_set_branch_offset(u32 insn, s32 offset);
489546

490-
int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
491-
int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
492-
493547
s32 aarch64_insn_adrp_get_offset(u32 insn);
494548
u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset);
495549

@@ -506,6 +560,7 @@ u32 aarch32_insn_mcr_extract_crm(u32 insn);
506560

507561
typedef bool (pstate_check_t)(unsigned long);
508562
extern pstate_check_t * const aarch32_opcode_cond_checks[16];
563+
509564
#endif /* __ASSEMBLY__ */
510565

511566
#endif /* __ASM_INSN_H */

arch/arm64/include/asm/kvm_asm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define __ARM_KVM_ASM_H__
99

1010
#include <asm/hyp_image.h>
11+
#include <asm/insn.h>
1112
#include <asm/virt.h>
1213

1314
#define ARM_EXIT_WITH_SERROR_BIT 31

arch/arm64/include/asm/patching.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
#ifndef __ASM_PATCHING_H
3+
#define __ASM_PATCHING_H
4+
5+
#include <linux/types.h>
6+
7+
int aarch64_insn_read(void *addr, u32 *insnp);
8+
int aarch64_insn_write(void *addr, u32 insn);
9+
10+
int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
11+
int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
12+
13+
#endif /* __ASM_PATCHING_H */

arch/arm64/kernel/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ KCOV_INSTRUMENT_idle.o := n
2424
obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
2525
entry-common.o entry-fpsimd.o process.o ptrace.o \
2626
setup.o signal.o sys.o stacktrace.o time.o traps.o \
27-
io.o vdso.o hyp-stub.o psci.o cpu_ops.o insn.o \
27+
io.o vdso.o hyp-stub.o psci.o cpu_ops.o \
2828
return_address.o cpuinfo.o cpu_errata.o \
2929
cpufeature.o alternative.o cacheinfo.o \
3030
smp.o smp_spin_table.o topology.o smccc-call.o \
31-
syscall.o proton-pack.o idreg-override.o idle.o
31+
syscall.o proton-pack.o idreg-override.o idle.o \
32+
patching.o
3233

3334
targets += efi-entry.o
3435

arch/arm64/kernel/cpufeature.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#include <asm/cpufeature.h>
7777
#include <asm/cpu_ops.h>
7878
#include <asm/fpsimd.h>
79+
#include <asm/insn.h>
7980
#include <asm/kvm_host.h>
8081
#include <asm/mmu_context.h>
8182
#include <asm/mte.h>

arch/arm64/kernel/ftrace.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <asm/debug-monitors.h>
1616
#include <asm/ftrace.h>
1717
#include <asm/insn.h>
18+
#include <asm/patching.h>
1819

1920
#ifdef CONFIG_DYNAMIC_FTRACE
2021
/*

arch/arm64/kernel/jump_label.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/kernel.h>
99
#include <linux/jump_label.h>
1010
#include <asm/insn.h>
11+
#include <asm/patching.h>
1112

1213
void arch_jump_label_transform(struct jump_entry *entry,
1314
enum jump_label_type type)

arch/arm64/kernel/kgdb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <asm/debug-monitors.h>
1919
#include <asm/insn.h>
20+
#include <asm/patching.h>
2021
#include <asm/traps.h>
2122

2223
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {

0 commit comments

Comments
 (0)