Skip to content

Commit cc0b8e1

Browse files
James Morsegregkh
authored andcommitted
arm64: insn: Add support for encoding DSB
commit 63de8abd97ddb9b758bd8f915ecbd18e1f1a87a0 upstream. To generate code in the eBPF epilogue that uses the DSB instruction, insn.c needs a heler to encode the type and domain. Re-use the crm encoding logic from the DMB instruction. Signed-off-by: James Morse <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 361dfa7 commit cc0b8e1

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

arch/arm64/include/asm/insn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
619619
}
620620
#endif
621621
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
622+
u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type);
622623

623624
s32 aarch64_get_branch_offset(u32 insn);
624625
u32 aarch64_set_branch_offset(u32 insn, s32 offset);

arch/arm64/lib/insn.c

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*
66
* Copyright (C) 2014-2016 Zi Shen Lim <[email protected]>
77
*/
8+
#include <linux/bitfield.h>
89
#include <linux/bitops.h>
910
#include <linux/bug.h>
1011
#include <linux/printk.h>
@@ -1630,47 +1631,60 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
16301631
return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
16311632
}
16321633

1633-
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
1634+
static u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type)
16341635
{
1635-
u32 opt;
1636-
u32 insn;
1637-
16381636
switch (type) {
16391637
case AARCH64_INSN_MB_SY:
1640-
opt = 0xf;
1641-
break;
1638+
return 0xf;
16421639
case AARCH64_INSN_MB_ST:
1643-
opt = 0xe;
1644-
break;
1640+
return 0xe;
16451641
case AARCH64_INSN_MB_LD:
1646-
opt = 0xd;
1647-
break;
1642+
return 0xd;
16481643
case AARCH64_INSN_MB_ISH:
1649-
opt = 0xb;
1650-
break;
1644+
return 0xb;
16511645
case AARCH64_INSN_MB_ISHST:
1652-
opt = 0xa;
1653-
break;
1646+
return 0xa;
16541647
case AARCH64_INSN_MB_ISHLD:
1655-
opt = 0x9;
1656-
break;
1648+
return 0x9;
16571649
case AARCH64_INSN_MB_NSH:
1658-
opt = 0x7;
1659-
break;
1650+
return 0x7;
16601651
case AARCH64_INSN_MB_NSHST:
1661-
opt = 0x6;
1662-
break;
1652+
return 0x6;
16631653
case AARCH64_INSN_MB_NSHLD:
1664-
opt = 0x5;
1665-
break;
1654+
return 0x5;
16661655
default:
1667-
pr_err("%s: unknown dmb type %d\n", __func__, type);
1656+
pr_err("%s: unknown barrier type %d\n", __func__, type);
16681657
return AARCH64_BREAK_FAULT;
16691658
}
1659+
}
1660+
1661+
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
1662+
{
1663+
u32 opt;
1664+
u32 insn;
1665+
1666+
opt = __get_barrier_crm_val(type);
1667+
if (opt == AARCH64_BREAK_FAULT)
1668+
return AARCH64_BREAK_FAULT;
16701669

16711670
insn = aarch64_insn_get_dmb_value();
16721671
insn &= ~GENMASK(11, 8);
16731672
insn |= (opt << 8);
16741673

16751674
return insn;
16761675
}
1676+
1677+
u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type)
1678+
{
1679+
u32 opt, insn;
1680+
1681+
opt = __get_barrier_crm_val(type);
1682+
if (opt == AARCH64_BREAK_FAULT)
1683+
return AARCH64_BREAK_FAULT;
1684+
1685+
insn = aarch64_insn_get_dsb_base_value();
1686+
insn &= ~GENMASK(11, 8);
1687+
insn |= (opt << 8);
1688+
1689+
return insn;
1690+
}

0 commit comments

Comments
 (0)