mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
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 <asavkov@redhat.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20240517075650.248801-4-asavkov@redhat.com
This commit is contained in:
parent
a71c0b09a1
commit
717756c9c8
|
|
@ -471,6 +471,7 @@
|
|||
#define PPC_RAW_VCMPEQUB_RC(vrt, vra, vrb) \
|
||||
(0x10000006 | ___PPC_RT(vrt) | ___PPC_RA(vra) | ___PPC_RB(vrb) | __PPC_RC21)
|
||||
#define PPC_RAW_LD(r, base, i) (0xe8000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_DS(i))
|
||||
#define PPC_RAW_LWA(r, base, i) (0xe8000002 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_DS(i))
|
||||
#define PPC_RAW_LWZ(r, base, i) (0x80000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
|
||||
#define PPC_RAW_LWZX(t, a, b) (0x7c00002e | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b))
|
||||
#define PPC_RAW_STD(r, base, i) (0xf8000000 | ___PPC_RS(r) | ___PPC_RA(base) | IMM_DS(i))
|
||||
|
|
|
|||
|
|
@ -937,13 +937,19 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
|
|||
*/
|
||||
/* dst = *(u8 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_B:
|
||||
case BPF_LDX | BPF_MEMSX | BPF_B:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
|
||||
case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
|
||||
/* dst = *(u16 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_H:
|
||||
case BPF_LDX | BPF_MEMSX | BPF_H:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
|
||||
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
|
||||
/* dst = *(u32 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_W:
|
||||
case BPF_LDX | BPF_MEMSX | BPF_W:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
|
||||
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
|
||||
/* dst = *(u64 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_DW:
|
||||
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
|
|||
* load only if addr is kernel address (see is_kernel_addr()), otherwise
|
||||
* set dst_reg=0 and move on.
|
||||
*/
|
||||
if (BPF_MODE(code) == BPF_PROBE_MEM) {
|
||||
if (BPF_MODE(code) == BPF_PROBE_MEM || BPF_MODE(code) == BPF_PROBE_MEMSX) {
|
||||
EMIT(PPC_RAW_ADDI(tmp1_reg, src_reg, off));
|
||||
if (IS_ENABLED(CONFIG_PPC_BOOK3E_64))
|
||||
PPC_LI64(tmp2_reg, 0x8000000000000000ul);
|
||||
|
|
@ -966,30 +972,47 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
|
|||
* Check if 'off' is word aligned for BPF_DW, because
|
||||
* we might generate two instructions.
|
||||
*/
|
||||
if (BPF_SIZE(code) == BPF_DW && (off & 3))
|
||||
if ((BPF_SIZE(code) == BPF_DW ||
|
||||
(BPF_SIZE(code) == BPF_B && BPF_MODE(code) == BPF_PROBE_MEMSX)) &&
|
||||
(off & 3))
|
||||
PPC_JMP((ctx->idx + 3) * 4);
|
||||
else
|
||||
PPC_JMP((ctx->idx + 2) * 4);
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case BPF_B:
|
||||
EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
|
||||
break;
|
||||
case BPF_H:
|
||||
EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
|
||||
break;
|
||||
case BPF_W:
|
||||
EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
|
||||
break;
|
||||
case BPF_DW:
|
||||
if (off % 4) {
|
||||
EMIT(PPC_RAW_LI(tmp1_reg, off));
|
||||
EMIT(PPC_RAW_LDX(dst_reg, src_reg, tmp1_reg));
|
||||
} else {
|
||||
EMIT(PPC_RAW_LD(dst_reg, src_reg, off));
|
||||
if (BPF_MODE(code) == BPF_MEMSX || BPF_MODE(code) == BPF_PROBE_MEMSX) {
|
||||
switch (size) {
|
||||
case BPF_B:
|
||||
EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
|
||||
EMIT(PPC_RAW_EXTSB(dst_reg, dst_reg));
|
||||
break;
|
||||
case BPF_H:
|
||||
EMIT(PPC_RAW_LHA(dst_reg, src_reg, off));
|
||||
break;
|
||||
case BPF_W:
|
||||
EMIT(PPC_RAW_LWA(dst_reg, src_reg, off));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (size) {
|
||||
case BPF_B:
|
||||
EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
|
||||
break;
|
||||
case BPF_H:
|
||||
EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
|
||||
break;
|
||||
case BPF_W:
|
||||
EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
|
||||
break;
|
||||
case BPF_DW:
|
||||
if (off % 4) {
|
||||
EMIT(PPC_RAW_LI(tmp1_reg, off));
|
||||
EMIT(PPC_RAW_LDX(dst_reg, src_reg, tmp1_reg));
|
||||
} else {
|
||||
EMIT(PPC_RAW_LD(dst_reg, src_reg, off));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (size != BPF_DW && insn_is_zext(&insn[i + 1]))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user