Skip to content

Commit 717756c

Browse files
sm00thmpe
authored andcommitted
powerpc64/bpf: jit support for sign extended load
Add jit support for sign extended load. Tested using test_bpf module. Signed-off-by: Artem Savkov <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://msgid.link/[email protected]
1 parent a71c0b0 commit 717756c

File tree

2 files changed

+43
-19
lines changed

2 files changed

+43
-19
lines changed

arch/powerpc/include/asm/ppc-opcode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@
471471
#define PPC_RAW_VCMPEQUB_RC(vrt, vra, vrb) \
472472
(0x10000006 | ___PPC_RT(vrt) | ___PPC_RA(vra) | ___PPC_RB(vrb) | __PPC_RC21)
473473
#define PPC_RAW_LD(r, base, i) (0xe8000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_DS(i))
474+
#define PPC_RAW_LWA(r, base, i) (0xe8000002 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_DS(i))
474475
#define PPC_RAW_LWZ(r, base, i) (0x80000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
475476
#define PPC_RAW_LWZX(t, a, b) (0x7c00002e | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b))
476477
#define PPC_RAW_STD(r, base, i) (0xf8000000 | ___PPC_RS(r) | ___PPC_RA(base) | IMM_DS(i))

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -937,13 +937,19 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
937937
*/
938938
/* dst = *(u8 *)(ul) (src + off) */
939939
case BPF_LDX | BPF_MEM | BPF_B:
940+
case BPF_LDX | BPF_MEMSX | BPF_B:
940941
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
942+
case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
941943
/* dst = *(u16 *)(ul) (src + off) */
942944
case BPF_LDX | BPF_MEM | BPF_H:
945+
case BPF_LDX | BPF_MEMSX | BPF_H:
943946
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
947+
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
944948
/* dst = *(u32 *)(ul) (src + off) */
945949
case BPF_LDX | BPF_MEM | BPF_W:
950+
case BPF_LDX | BPF_MEMSX | BPF_W:
946951
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
952+
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
947953
/* dst = *(u64 *)(ul) (src + off) */
948954
case BPF_LDX | BPF_MEM | BPF_DW:
949955
case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
@@ -953,7 +959,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
953959
* load only if addr is kernel address (see is_kernel_addr()), otherwise
954960
* set dst_reg=0 and move on.
955961
*/
956-
if (BPF_MODE(code) == BPF_PROBE_MEM) {
962+
if (BPF_MODE(code) == BPF_PROBE_MEM || BPF_MODE(code) == BPF_PROBE_MEMSX) {
957963
EMIT(PPC_RAW_ADDI(tmp1_reg, src_reg, off));
958964
if (IS_ENABLED(CONFIG_PPC_BOOK3E_64))
959965
PPC_LI64(tmp2_reg, 0x8000000000000000ul);
@@ -966,30 +972,47 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
966972
* Check if 'off' is word aligned for BPF_DW, because
967973
* we might generate two instructions.
968974
*/
969-
if (BPF_SIZE(code) == BPF_DW && (off & 3))
975+
if ((BPF_SIZE(code) == BPF_DW ||
976+
(BPF_SIZE(code) == BPF_B && BPF_MODE(code) == BPF_PROBE_MEMSX)) &&
977+
(off & 3))
970978
PPC_JMP((ctx->idx + 3) * 4);
971979
else
972980
PPC_JMP((ctx->idx + 2) * 4);
973981
}
974982

975-
switch (size) {
976-
case BPF_B:
977-
EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
978-
break;
979-
case BPF_H:
980-
EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
981-
break;
982-
case BPF_W:
983-
EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
984-
break;
985-
case BPF_DW:
986-
if (off % 4) {
987-
EMIT(PPC_RAW_LI(tmp1_reg, off));
988-
EMIT(PPC_RAW_LDX(dst_reg, src_reg, tmp1_reg));
989-
} else {
990-
EMIT(PPC_RAW_LD(dst_reg, src_reg, off));
983+
if (BPF_MODE(code) == BPF_MEMSX || BPF_MODE(code) == BPF_PROBE_MEMSX) {
984+
switch (size) {
985+
case BPF_B:
986+
EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
987+
EMIT(PPC_RAW_EXTSB(dst_reg, dst_reg));
988+
break;
989+
case BPF_H:
990+
EMIT(PPC_RAW_LHA(dst_reg, src_reg, off));
991+
break;
992+
case BPF_W:
993+
EMIT(PPC_RAW_LWA(dst_reg, src_reg, off));
994+
break;
995+
}
996+
} else {
997+
switch (size) {
998+
case BPF_B:
999+
EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
1000+
break;
1001+
case BPF_H:
1002+
EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
1003+
break;
1004+
case BPF_W:
1005+
EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
1006+
break;
1007+
case BPF_DW:
1008+
if (off % 4) {
1009+
EMIT(PPC_RAW_LI(tmp1_reg, off));
1010+
EMIT(PPC_RAW_LDX(dst_reg, src_reg, tmp1_reg));
1011+
} else {
1012+
EMIT(PPC_RAW_LD(dst_reg, src_reg, off));
1013+
}
1014+
break;
9911015
}
992-
break;
9931016
}
9941017

9951018
if (size != BPF_DW && insn_is_zext(&insn[i + 1]))

0 commit comments

Comments
 (0)