Skip to content

Commit 5dc6155

Browse files
seehearfeelchenhuacai
authored andcommitted
LoongArch: Add BPF JIT support
BPF programs are normally handled by a BPF interpreter, add BPF JIT support for LoongArch to allow the kernel to generate native code when a program is loaded into the kernel. This will significantly speed-up processing of BPF programs. Co-developed-by: Youling Tang <[email protected]> Signed-off-by: Youling Tang <[email protected]> Signed-off-by: Tiezhu Yang <[email protected]> Signed-off-by: Huacai Chen <[email protected]>
1 parent 4e59e5a commit 5dc6155

File tree

7 files changed

+1700
-0
lines changed

7 files changed

+1700
-0
lines changed

arch/loongarch/Kbuild

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
obj-y += kernel/
22
obj-y += mm/
3+
obj-y += net/
34
obj-y += vdso/
45

56
# for cleaning

arch/loongarch/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ config LOONGARCH
8787
select HAVE_CONTEXT_TRACKING_USER
8888
select HAVE_DEBUG_STACKOVERFLOW
8989
select HAVE_DMA_CONTIGUOUS
90+
select HAVE_EBPF_JIT
9091
select HAVE_EXIT_THREAD
9192
select HAVE_FAST_GUP
9293
select HAVE_GENERIC_VDSO

arch/loongarch/include/asm/inst.h

+221
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,225 @@ static inline bool unsigned_imm_check(unsigned long val, unsigned int bit)
345345
return val < (1UL << bit);
346346
}
347347

348+
#define DEF_EMIT_REG0I26_FORMAT(NAME, OP) \
349+
static inline void emit_##NAME(union loongarch_instruction *insn, \
350+
int offset) \
351+
{ \
352+
unsigned int immediate_l, immediate_h; \
353+
\
354+
immediate_l = offset & 0xffff; \
355+
offset >>= 16; \
356+
immediate_h = offset & 0x3ff; \
357+
\
358+
insn->reg0i26_format.opcode = OP; \
359+
insn->reg0i26_format.immediate_l = immediate_l; \
360+
insn->reg0i26_format.immediate_h = immediate_h; \
361+
}
362+
363+
DEF_EMIT_REG0I26_FORMAT(b, b_op)
364+
365+
#define DEF_EMIT_REG1I20_FORMAT(NAME, OP) \
366+
static inline void emit_##NAME(union loongarch_instruction *insn, \
367+
enum loongarch_gpr rd, int imm) \
368+
{ \
369+
insn->reg1i20_format.opcode = OP; \
370+
insn->reg1i20_format.immediate = imm; \
371+
insn->reg1i20_format.rd = rd; \
372+
}
373+
374+
DEF_EMIT_REG1I20_FORMAT(lu12iw, lu12iw_op)
375+
DEF_EMIT_REG1I20_FORMAT(lu32id, lu32id_op)
376+
DEF_EMIT_REG1I20_FORMAT(pcaddu18i, pcaddu18i_op)
377+
378+
#define DEF_EMIT_REG2_FORMAT(NAME, OP) \
379+
static inline void emit_##NAME(union loongarch_instruction *insn, \
380+
enum loongarch_gpr rd, \
381+
enum loongarch_gpr rj) \
382+
{ \
383+
insn->reg2_format.opcode = OP; \
384+
insn->reg2_format.rd = rd; \
385+
insn->reg2_format.rj = rj; \
386+
}
387+
388+
DEF_EMIT_REG2_FORMAT(revb2h, revb2h_op)
389+
DEF_EMIT_REG2_FORMAT(revb2w, revb2w_op)
390+
DEF_EMIT_REG2_FORMAT(revbd, revbd_op)
391+
392+
#define DEF_EMIT_REG2I5_FORMAT(NAME, OP) \
393+
static inline void emit_##NAME(union loongarch_instruction *insn, \
394+
enum loongarch_gpr rd, \
395+
enum loongarch_gpr rj, \
396+
int imm) \
397+
{ \
398+
insn->reg2i5_format.opcode = OP; \
399+
insn->reg2i5_format.immediate = imm; \
400+
insn->reg2i5_format.rd = rd; \
401+
insn->reg2i5_format.rj = rj; \
402+
}
403+
404+
DEF_EMIT_REG2I5_FORMAT(slliw, slliw_op)
405+
DEF_EMIT_REG2I5_FORMAT(srliw, srliw_op)
406+
DEF_EMIT_REG2I5_FORMAT(sraiw, sraiw_op)
407+
408+
#define DEF_EMIT_REG2I6_FORMAT(NAME, OP) \
409+
static inline void emit_##NAME(union loongarch_instruction *insn, \
410+
enum loongarch_gpr rd, \
411+
enum loongarch_gpr rj, \
412+
int imm) \
413+
{ \
414+
insn->reg2i6_format.opcode = OP; \
415+
insn->reg2i6_format.immediate = imm; \
416+
insn->reg2i6_format.rd = rd; \
417+
insn->reg2i6_format.rj = rj; \
418+
}
419+
420+
DEF_EMIT_REG2I6_FORMAT(sllid, sllid_op)
421+
DEF_EMIT_REG2I6_FORMAT(srlid, srlid_op)
422+
DEF_EMIT_REG2I6_FORMAT(sraid, sraid_op)
423+
424+
#define DEF_EMIT_REG2I12_FORMAT(NAME, OP) \
425+
static inline void emit_##NAME(union loongarch_instruction *insn, \
426+
enum loongarch_gpr rd, \
427+
enum loongarch_gpr rj, \
428+
int imm) \
429+
{ \
430+
insn->reg2i12_format.opcode = OP; \
431+
insn->reg2i12_format.immediate = imm; \
432+
insn->reg2i12_format.rd = rd; \
433+
insn->reg2i12_format.rj = rj; \
434+
}
435+
436+
DEF_EMIT_REG2I12_FORMAT(addiw, addiw_op)
437+
DEF_EMIT_REG2I12_FORMAT(addid, addid_op)
438+
DEF_EMIT_REG2I12_FORMAT(lu52id, lu52id_op)
439+
DEF_EMIT_REG2I12_FORMAT(andi, andi_op)
440+
DEF_EMIT_REG2I12_FORMAT(ori, ori_op)
441+
DEF_EMIT_REG2I12_FORMAT(xori, xori_op)
442+
DEF_EMIT_REG2I12_FORMAT(ldbu, ldbu_op)
443+
DEF_EMIT_REG2I12_FORMAT(ldhu, ldhu_op)
444+
DEF_EMIT_REG2I12_FORMAT(ldwu, ldwu_op)
445+
DEF_EMIT_REG2I12_FORMAT(ldd, ldd_op)
446+
DEF_EMIT_REG2I12_FORMAT(stb, stb_op)
447+
DEF_EMIT_REG2I12_FORMAT(sth, sth_op)
448+
DEF_EMIT_REG2I12_FORMAT(stw, stw_op)
449+
DEF_EMIT_REG2I12_FORMAT(std, std_op)
450+
451+
#define DEF_EMIT_REG2I14_FORMAT(NAME, OP) \
452+
static inline void emit_##NAME(union loongarch_instruction *insn, \
453+
enum loongarch_gpr rd, \
454+
enum loongarch_gpr rj, \
455+
int imm) \
456+
{ \
457+
insn->reg2i14_format.opcode = OP; \
458+
insn->reg2i14_format.immediate = imm; \
459+
insn->reg2i14_format.rd = rd; \
460+
insn->reg2i14_format.rj = rj; \
461+
}
462+
463+
DEF_EMIT_REG2I14_FORMAT(llw, llw_op)
464+
DEF_EMIT_REG2I14_FORMAT(scw, scw_op)
465+
DEF_EMIT_REG2I14_FORMAT(lld, lld_op)
466+
DEF_EMIT_REG2I14_FORMAT(scd, scd_op)
467+
DEF_EMIT_REG2I14_FORMAT(ldptrw, ldptrw_op)
468+
DEF_EMIT_REG2I14_FORMAT(stptrw, stptrw_op)
469+
DEF_EMIT_REG2I14_FORMAT(ldptrd, ldptrd_op)
470+
DEF_EMIT_REG2I14_FORMAT(stptrd, stptrd_op)
471+
472+
#define DEF_EMIT_REG2I16_FORMAT(NAME, OP) \
473+
static inline void emit_##NAME(union loongarch_instruction *insn, \
474+
enum loongarch_gpr rj, \
475+
enum loongarch_gpr rd, \
476+
int offset) \
477+
{ \
478+
insn->reg2i16_format.opcode = OP; \
479+
insn->reg2i16_format.immediate = offset; \
480+
insn->reg2i16_format.rj = rj; \
481+
insn->reg2i16_format.rd = rd; \
482+
}
483+
484+
DEF_EMIT_REG2I16_FORMAT(beq, beq_op)
485+
DEF_EMIT_REG2I16_FORMAT(bne, bne_op)
486+
DEF_EMIT_REG2I16_FORMAT(blt, blt_op)
487+
DEF_EMIT_REG2I16_FORMAT(bge, bge_op)
488+
DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op)
489+
DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op)
490+
DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op)
491+
492+
#define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP) \
493+
static inline void emit_##NAME(union loongarch_instruction *insn, \
494+
enum loongarch_gpr rd, \
495+
enum loongarch_gpr rj, \
496+
int msbd, \
497+
int lsbd) \
498+
{ \
499+
insn->reg2bstrd_format.opcode = OP; \
500+
insn->reg2bstrd_format.msbd = msbd; \
501+
insn->reg2bstrd_format.lsbd = lsbd; \
502+
insn->reg2bstrd_format.rj = rj; \
503+
insn->reg2bstrd_format.rd = rd; \
504+
}
505+
506+
DEF_EMIT_REG2BSTRD_FORMAT(bstrpickd, bstrpickd_op)
507+
508+
#define DEF_EMIT_REG3_FORMAT(NAME, OP) \
509+
static inline void emit_##NAME(union loongarch_instruction *insn, \
510+
enum loongarch_gpr rd, \
511+
enum loongarch_gpr rj, \
512+
enum loongarch_gpr rk) \
513+
{ \
514+
insn->reg3_format.opcode = OP; \
515+
insn->reg3_format.rd = rd; \
516+
insn->reg3_format.rj = rj; \
517+
insn->reg3_format.rk = rk; \
518+
}
519+
520+
DEF_EMIT_REG3_FORMAT(addd, addd_op)
521+
DEF_EMIT_REG3_FORMAT(subd, subd_op)
522+
DEF_EMIT_REG3_FORMAT(muld, muld_op)
523+
DEF_EMIT_REG3_FORMAT(divdu, divdu_op)
524+
DEF_EMIT_REG3_FORMAT(moddu, moddu_op)
525+
DEF_EMIT_REG3_FORMAT(and, and_op)
526+
DEF_EMIT_REG3_FORMAT(or, or_op)
527+
DEF_EMIT_REG3_FORMAT(xor, xor_op)
528+
DEF_EMIT_REG3_FORMAT(sllw, sllw_op)
529+
DEF_EMIT_REG3_FORMAT(slld, slld_op)
530+
DEF_EMIT_REG3_FORMAT(srlw, srlw_op)
531+
DEF_EMIT_REG3_FORMAT(srld, srld_op)
532+
DEF_EMIT_REG3_FORMAT(sraw, sraw_op)
533+
DEF_EMIT_REG3_FORMAT(srad, srad_op)
534+
DEF_EMIT_REG3_FORMAT(ldxbu, ldxbu_op)
535+
DEF_EMIT_REG3_FORMAT(ldxhu, ldxhu_op)
536+
DEF_EMIT_REG3_FORMAT(ldxwu, ldxwu_op)
537+
DEF_EMIT_REG3_FORMAT(ldxd, ldxd_op)
538+
DEF_EMIT_REG3_FORMAT(stxb, stxb_op)
539+
DEF_EMIT_REG3_FORMAT(stxh, stxh_op)
540+
DEF_EMIT_REG3_FORMAT(stxw, stxw_op)
541+
DEF_EMIT_REG3_FORMAT(stxd, stxd_op)
542+
DEF_EMIT_REG3_FORMAT(amaddw, amaddw_op)
543+
DEF_EMIT_REG3_FORMAT(amaddd, amaddd_op)
544+
DEF_EMIT_REG3_FORMAT(amandw, amandw_op)
545+
DEF_EMIT_REG3_FORMAT(amandd, amandd_op)
546+
DEF_EMIT_REG3_FORMAT(amorw, amorw_op)
547+
DEF_EMIT_REG3_FORMAT(amord, amord_op)
548+
DEF_EMIT_REG3_FORMAT(amxorw, amxorw_op)
549+
DEF_EMIT_REG3_FORMAT(amxord, amxord_op)
550+
DEF_EMIT_REG3_FORMAT(amswapw, amswapw_op)
551+
DEF_EMIT_REG3_FORMAT(amswapd, amswapd_op)
552+
553+
#define DEF_EMIT_REG3SA2_FORMAT(NAME, OP) \
554+
static inline void emit_##NAME(union loongarch_instruction *insn, \
555+
enum loongarch_gpr rd, \
556+
enum loongarch_gpr rj, \
557+
enum loongarch_gpr rk, \
558+
int imm) \
559+
{ \
560+
insn->reg3sa2_format.opcode = OP; \
561+
insn->reg3sa2_format.immediate = imm; \
562+
insn->reg3sa2_format.rd = rd; \
563+
insn->reg3sa2_format.rj = rj; \
564+
insn->reg3sa2_format.rk = rk; \
565+
}
566+
567+
DEF_EMIT_REG3SA2_FORMAT(alsld, alsld_op)
568+
348569
#endif /* _ASM_INST_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2+
#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
3+
#define _UAPI__ASM_BPF_PERF_EVENT_H__
4+
5+
#include <linux/ptrace.h>
6+
7+
typedef struct user_pt_regs bpf_user_pt_regs_t;
8+
9+
#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */

arch/loongarch/net/Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
#
3+
# Makefile for arch/loongarch/net
4+
#
5+
# Copyright (C) 2022 Loongson Technology Corporation Limited
6+
#
7+
obj-$(CONFIG_BPF_JIT) += bpf_jit.o

0 commit comments

Comments
 (0)