Skip to content

Commit 63de8ab

Browse files
author
James Morse
committed
arm64: insn: Add support for encoding DSB
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]>
1 parent 92a09c4 commit 63de8ab

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
@@ -706,6 +706,7 @@ u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
706706
}
707707
#endif
708708
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
709+
u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type);
709710
u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
710711
enum aarch64_insn_system_register sysreg);
711712

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>
@@ -1500,43 +1501,41 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
15001501
return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
15011502
}
15021503

1503-
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
1504+
static u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type)
15041505
{
1505-
u32 opt;
1506-
u32 insn;
1507-
15081506
switch (type) {
15091507
case AARCH64_INSN_MB_SY:
1510-
opt = 0xf;
1511-
break;
1508+
return 0xf;
15121509
case AARCH64_INSN_MB_ST:
1513-
opt = 0xe;
1514-
break;
1510+
return 0xe;
15151511
case AARCH64_INSN_MB_LD:
1516-
opt = 0xd;
1517-
break;
1512+
return 0xd;
15181513
case AARCH64_INSN_MB_ISH:
1519-
opt = 0xb;
1520-
break;
1514+
return 0xb;
15211515
case AARCH64_INSN_MB_ISHST:
1522-
opt = 0xa;
1523-
break;
1516+
return 0xa;
15241517
case AARCH64_INSN_MB_ISHLD:
1525-
opt = 0x9;
1526-
break;
1518+
return 0x9;
15271519
case AARCH64_INSN_MB_NSH:
1528-
opt = 0x7;
1529-
break;
1520+
return 0x7;
15301521
case AARCH64_INSN_MB_NSHST:
1531-
opt = 0x6;
1532-
break;
1522+
return 0x6;
15331523
case AARCH64_INSN_MB_NSHLD:
1534-
opt = 0x5;
1535-
break;
1524+
return 0x5;
15361525
default:
1537-
pr_err("%s: unknown dmb type %d\n", __func__, type);
1526+
pr_err("%s: unknown barrier type %d\n", __func__, type);
15381527
return AARCH64_BREAK_FAULT;
15391528
}
1529+
}
1530+
1531+
u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
1532+
{
1533+
u32 opt;
1534+
u32 insn;
1535+
1536+
opt = __get_barrier_crm_val(type);
1537+
if (opt == AARCH64_BREAK_FAULT)
1538+
return AARCH64_BREAK_FAULT;
15401539

15411540
insn = aarch64_insn_get_dmb_value();
15421541
insn &= ~GENMASK(11, 8);
@@ -1545,6 +1544,21 @@ u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
15451544
return insn;
15461545
}
15471546

1547+
u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type)
1548+
{
1549+
u32 opt, insn;
1550+
1551+
opt = __get_barrier_crm_val(type);
1552+
if (opt == AARCH64_BREAK_FAULT)
1553+
return AARCH64_BREAK_FAULT;
1554+
1555+
insn = aarch64_insn_get_dsb_base_value();
1556+
insn &= ~GENMASK(11, 8);
1557+
insn |= (opt << 8);
1558+
1559+
return insn;
1560+
}
1561+
15481562
u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
15491563
enum aarch64_insn_system_register sysreg)
15501564
{

0 commit comments

Comments
 (0)