bpf_jit.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * BPF JIT compiler for LoongArch
  4. *
  5. * Copyright (C) 2022 Loongson Technology Corporation Limited
  6. */
  7. #include "bpf_jit.h"
  8. #define REG_TCC LOONGARCH_GPR_A6
  9. #define TCC_SAVED LOONGARCH_GPR_S5
  10. #define SAVE_RA BIT(0)
  11. #define SAVE_TCC BIT(1)
  12. static const int regmap[] = {
  13. /* return value from in-kernel function, and exit value for eBPF program */
  14. [BPF_REG_0] = LOONGARCH_GPR_A5,
  15. /* arguments from eBPF program to in-kernel function */
  16. [BPF_REG_1] = LOONGARCH_GPR_A0,
  17. [BPF_REG_2] = LOONGARCH_GPR_A1,
  18. [BPF_REG_3] = LOONGARCH_GPR_A2,
  19. [BPF_REG_4] = LOONGARCH_GPR_A3,
  20. [BPF_REG_5] = LOONGARCH_GPR_A4,
  21. /* callee saved registers that in-kernel function will preserve */
  22. [BPF_REG_6] = LOONGARCH_GPR_S0,
  23. [BPF_REG_7] = LOONGARCH_GPR_S1,
  24. [BPF_REG_8] = LOONGARCH_GPR_S2,
  25. [BPF_REG_9] = LOONGARCH_GPR_S3,
  26. /* read-only frame pointer to access stack */
  27. [BPF_REG_FP] = LOONGARCH_GPR_S4,
  28. /* temporary register for blinding constants */
  29. [BPF_REG_AX] = LOONGARCH_GPR_T0,
  30. };
  31. static void mark_call(struct jit_ctx *ctx)
  32. {
  33. ctx->flags |= SAVE_RA;
  34. }
  35. static void mark_tail_call(struct jit_ctx *ctx)
  36. {
  37. ctx->flags |= SAVE_TCC;
  38. }
  39. static bool seen_call(struct jit_ctx *ctx)
  40. {
  41. return (ctx->flags & SAVE_RA);
  42. }
  43. static bool seen_tail_call(struct jit_ctx *ctx)
  44. {
  45. return (ctx->flags & SAVE_TCC);
  46. }
  47. static u8 tail_call_reg(struct jit_ctx *ctx)
  48. {
  49. if (seen_call(ctx))
  50. return TCC_SAVED;
  51. return REG_TCC;
  52. }
  53. /*
  54. * eBPF prog stack layout:
  55. *
  56. * high
  57. * original $sp ------------> +-------------------------+ <--LOONGARCH_GPR_FP
  58. * | $ra |
  59. * +-------------------------+
  60. * | $fp |
  61. * +-------------------------+
  62. * | $s0 |
  63. * +-------------------------+
  64. * | $s1 |
  65. * +-------------------------+
  66. * | $s2 |
  67. * +-------------------------+
  68. * | $s3 |
  69. * +-------------------------+
  70. * | $s4 |
  71. * +-------------------------+
  72. * | $s5 |
  73. * +-------------------------+ <--BPF_REG_FP
  74. * | prog->aux->stack_depth |
  75. * | (optional) |
  76. * current $sp -------------> +-------------------------+
  77. * low
  78. */
  79. static void build_prologue(struct jit_ctx *ctx)
  80. {
  81. int stack_adjust = 0, store_offset, bpf_stack_adjust;
  82. bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16);
  83. /* To store ra, fp, s0, s1, s2, s3, s4 and s5. */
  84. stack_adjust += sizeof(long) * 8;
  85. stack_adjust = round_up(stack_adjust, 16);
  86. stack_adjust += bpf_stack_adjust;
  87. /*
  88. * First instruction initializes the tail call count (TCC).
  89. * On tail call we skip this instruction, and the TCC is
  90. * passed in REG_TCC from the caller.
  91. */
  92. emit_insn(ctx, addid, REG_TCC, LOONGARCH_GPR_ZERO, MAX_TAIL_CALL_CNT);
  93. emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_adjust);
  94. store_offset = stack_adjust - sizeof(long);
  95. emit_insn(ctx, std, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, store_offset);
  96. store_offset -= sizeof(long);
  97. emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, store_offset);
  98. store_offset -= sizeof(long);
  99. emit_insn(ctx, std, LOONGARCH_GPR_S0, LOONGARCH_GPR_SP, store_offset);
  100. store_offset -= sizeof(long);
  101. emit_insn(ctx, std, LOONGARCH_GPR_S1, LOONGARCH_GPR_SP, store_offset);
  102. store_offset -= sizeof(long);
  103. emit_insn(ctx, std, LOONGARCH_GPR_S2, LOONGARCH_GPR_SP, store_offset);
  104. store_offset -= sizeof(long);
  105. emit_insn(ctx, std, LOONGARCH_GPR_S3, LOONGARCH_GPR_SP, store_offset);
  106. store_offset -= sizeof(long);
  107. emit_insn(ctx, std, LOONGARCH_GPR_S4, LOONGARCH_GPR_SP, store_offset);
  108. store_offset -= sizeof(long);
  109. emit_insn(ctx, std, LOONGARCH_GPR_S5, LOONGARCH_GPR_SP, store_offset);
  110. emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_adjust);
  111. if (bpf_stack_adjust)
  112. emit_insn(ctx, addid, regmap[BPF_REG_FP], LOONGARCH_GPR_SP, bpf_stack_adjust);
  113. /*
  114. * Program contains calls and tail calls, so REG_TCC need
  115. * to be saved across calls.
  116. */
  117. if (seen_tail_call(ctx) && seen_call(ctx))
  118. move_reg(ctx, TCC_SAVED, REG_TCC);
  119. else
  120. emit_insn(ctx, nop);
  121. ctx->stack_size = stack_adjust;
  122. }
  123. static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call)
  124. {
  125. int stack_adjust = ctx->stack_size;
  126. int load_offset;
  127. load_offset = stack_adjust - sizeof(long);
  128. emit_insn(ctx, ldd, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, load_offset);
  129. load_offset -= sizeof(long);
  130. emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, load_offset);
  131. load_offset -= sizeof(long);
  132. emit_insn(ctx, ldd, LOONGARCH_GPR_S0, LOONGARCH_GPR_SP, load_offset);
  133. load_offset -= sizeof(long);
  134. emit_insn(ctx, ldd, LOONGARCH_GPR_S1, LOONGARCH_GPR_SP, load_offset);
  135. load_offset -= sizeof(long);
  136. emit_insn(ctx, ldd, LOONGARCH_GPR_S2, LOONGARCH_GPR_SP, load_offset);
  137. load_offset -= sizeof(long);
  138. emit_insn(ctx, ldd, LOONGARCH_GPR_S3, LOONGARCH_GPR_SP, load_offset);
  139. load_offset -= sizeof(long);
  140. emit_insn(ctx, ldd, LOONGARCH_GPR_S4, LOONGARCH_GPR_SP, load_offset);
  141. load_offset -= sizeof(long);
  142. emit_insn(ctx, ldd, LOONGARCH_GPR_S5, LOONGARCH_GPR_SP, load_offset);
  143. emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_adjust);
  144. if (!is_tail_call) {
  145. /* Set return value */
  146. emit_insn(ctx, addiw, LOONGARCH_GPR_A0, regmap[BPF_REG_0], 0);
  147. /* Return to the caller */
  148. emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
  149. } else {
  150. /*
  151. * Call the next bpf prog and skip the first instruction
  152. * of TCC initialization.
  153. */
  154. emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 1);
  155. }
  156. }
  157. static void build_epilogue(struct jit_ctx *ctx)
  158. {
  159. __build_epilogue(ctx, false);
  160. }
  161. bool bpf_jit_supports_kfunc_call(void)
  162. {
  163. return true;
  164. }
  165. bool bpf_jit_supports_far_kfunc_call(void)
  166. {
  167. return true;
  168. }
  169. static int emit_bpf_tail_call(struct jit_ctx *ctx, int insn)
  170. {
  171. int off, tc_ninsn = 0;
  172. u8 tcc = tail_call_reg(ctx);
  173. u8 a1 = LOONGARCH_GPR_A1;
  174. u8 a2 = LOONGARCH_GPR_A2;
  175. u8 t1 = LOONGARCH_GPR_T1;
  176. u8 t2 = LOONGARCH_GPR_T2;
  177. u8 t3 = LOONGARCH_GPR_T3;
  178. const int idx0 = ctx->idx;
  179. #define cur_offset (ctx->idx - idx0)
  180. #define jmp_offset (tc_ninsn - (cur_offset))
  181. /*
  182. * a0: &ctx
  183. * a1: &array
  184. * a2: index
  185. *
  186. * if (index >= array->map.max_entries)
  187. * goto out;
  188. */
  189. tc_ninsn = insn ? ctx->offset[insn+1] - ctx->offset[insn] : ctx->offset[0];
  190. off = offsetof(struct bpf_array, map.max_entries);
  191. emit_insn(ctx, ldwu, t1, a1, off);
  192. /* bgeu $a2, $t1, jmp_offset */
  193. if (emit_tailcall_jmp(ctx, BPF_JGE, a2, t1, jmp_offset) < 0)
  194. goto toofar;
  195. /*
  196. * if (--TCC < 0)
  197. * goto out;
  198. */
  199. emit_insn(ctx, addid, REG_TCC, tcc, -1);
  200. if (emit_tailcall_jmp(ctx, BPF_JSLT, REG_TCC, LOONGARCH_GPR_ZERO, jmp_offset) < 0)
  201. goto toofar;
  202. /*
  203. * prog = array->ptrs[index];
  204. * if (!prog)
  205. * goto out;
  206. */
  207. emit_insn(ctx, alsld, t2, a2, a1, 2);
  208. off = offsetof(struct bpf_array, ptrs);
  209. emit_insn(ctx, ldd, t2, t2, off);
  210. /* beq $t2, $zero, jmp_offset */
  211. if (emit_tailcall_jmp(ctx, BPF_JEQ, t2, LOONGARCH_GPR_ZERO, jmp_offset) < 0)
  212. goto toofar;
  213. /* goto *(prog->bpf_func + 4); */
  214. off = offsetof(struct bpf_prog, bpf_func);
  215. emit_insn(ctx, ldd, t3, t2, off);
  216. __build_epilogue(ctx, true);
  217. return 0;
  218. toofar:
  219. pr_info_once("tail_call: jump too far\n");
  220. return -1;
  221. #undef cur_offset
  222. #undef jmp_offset
  223. }
  224. static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
  225. {
  226. const u8 t1 = LOONGARCH_GPR_T1;
  227. const u8 t2 = LOONGARCH_GPR_T2;
  228. const u8 t3 = LOONGARCH_GPR_T3;
  229. const u8 r0 = regmap[BPF_REG_0];
  230. const u8 src = regmap[insn->src_reg];
  231. const u8 dst = regmap[insn->dst_reg];
  232. const s16 off = insn->off;
  233. const s32 imm = insn->imm;
  234. const bool isdw = BPF_SIZE(insn->code) == BPF_DW;
  235. move_imm(ctx, t1, off, false);
  236. emit_insn(ctx, addd, t1, dst, t1);
  237. move_reg(ctx, t3, src);
  238. switch (imm) {
  239. /* lock *(size *)(dst + off) <op>= src */
  240. case BPF_ADD:
  241. if (isdw)
  242. emit_insn(ctx, amaddd, t2, t1, src);
  243. else
  244. emit_insn(ctx, amaddw, t2, t1, src);
  245. break;
  246. case BPF_AND:
  247. if (isdw)
  248. emit_insn(ctx, amandd, t2, t1, src);
  249. else
  250. emit_insn(ctx, amandw, t2, t1, src);
  251. break;
  252. case BPF_OR:
  253. if (isdw)
  254. emit_insn(ctx, amord, t2, t1, src);
  255. else
  256. emit_insn(ctx, amorw, t2, t1, src);
  257. break;
  258. case BPF_XOR:
  259. if (isdw)
  260. emit_insn(ctx, amxord, t2, t1, src);
  261. else
  262. emit_insn(ctx, amxorw, t2, t1, src);
  263. break;
  264. /* src = atomic_fetch_<op>(dst + off, src) */
  265. case BPF_ADD | BPF_FETCH:
  266. if (isdw) {
  267. emit_insn(ctx, amaddd, src, t1, t3);
  268. } else {
  269. emit_insn(ctx, amaddw, src, t1, t3);
  270. emit_zext_32(ctx, src, true);
  271. }
  272. break;
  273. case BPF_AND | BPF_FETCH:
  274. if (isdw) {
  275. emit_insn(ctx, amandd, src, t1, t3);
  276. } else {
  277. emit_insn(ctx, amandw, src, t1, t3);
  278. emit_zext_32(ctx, src, true);
  279. }
  280. break;
  281. case BPF_OR | BPF_FETCH:
  282. if (isdw) {
  283. emit_insn(ctx, amord, src, t1, t3);
  284. } else {
  285. emit_insn(ctx, amorw, src, t1, t3);
  286. emit_zext_32(ctx, src, true);
  287. }
  288. break;
  289. case BPF_XOR | BPF_FETCH:
  290. if (isdw) {
  291. emit_insn(ctx, amxord, src, t1, t3);
  292. } else {
  293. emit_insn(ctx, amxorw, src, t1, t3);
  294. emit_zext_32(ctx, src, true);
  295. }
  296. break;
  297. /* src = atomic_xchg(dst + off, src); */
  298. case BPF_XCHG:
  299. if (isdw) {
  300. emit_insn(ctx, amswapd, src, t1, t3);
  301. } else {
  302. emit_insn(ctx, amswapw, src, t1, t3);
  303. emit_zext_32(ctx, src, true);
  304. }
  305. break;
  306. /* r0 = atomic_cmpxchg(dst + off, r0, src); */
  307. case BPF_CMPXCHG:
  308. move_reg(ctx, t2, r0);
  309. if (isdw) {
  310. emit_insn(ctx, lld, r0, t1, 0);
  311. emit_insn(ctx, bne, t2, r0, 4);
  312. move_reg(ctx, t3, src);
  313. emit_insn(ctx, scd, t3, t1, 0);
  314. emit_insn(ctx, beq, t3, LOONGARCH_GPR_ZERO, -4);
  315. } else {
  316. emit_insn(ctx, llw, r0, t1, 0);
  317. emit_zext_32(ctx, t2, true);
  318. emit_zext_32(ctx, r0, true);
  319. emit_insn(ctx, bne, t2, r0, 4);
  320. move_reg(ctx, t3, src);
  321. emit_insn(ctx, scw, t3, t1, 0);
  322. emit_insn(ctx, beq, t3, LOONGARCH_GPR_ZERO, -6);
  323. emit_zext_32(ctx, r0, true);
  324. }
  325. break;
  326. }
  327. }
  328. static bool is_signed_bpf_cond(u8 cond)
  329. {
  330. return cond == BPF_JSGT || cond == BPF_JSLT ||
  331. cond == BPF_JSGE || cond == BPF_JSLE;
  332. }
  333. #define BPF_FIXUP_REG_MASK GENMASK(31, 27)
  334. #define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0)
  335. bool ex_handler_bpf(const struct exception_table_entry *ex,
  336. struct pt_regs *regs)
  337. {
  338. int dst_reg = FIELD_GET(BPF_FIXUP_REG_MASK, ex->fixup);
  339. off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup);
  340. regs->regs[dst_reg] = 0;
  341. regs->csr_era = (unsigned long)&ex->fixup - offset;
  342. return true;
  343. }
  344. /* For accesses to BTF pointers, add an entry to the exception table */
  345. static int add_exception_handler(const struct bpf_insn *insn,
  346. struct jit_ctx *ctx,
  347. int dst_reg)
  348. {
  349. unsigned long pc;
  350. off_t offset;
  351. struct exception_table_entry *ex;
  352. if (!ctx->image || !ctx->prog->aux->extable)
  353. return 0;
  354. if (BPF_MODE(insn->code) != BPF_PROBE_MEM &&
  355. BPF_MODE(insn->code) != BPF_PROBE_MEMSX)
  356. return 0;
  357. if (WARN_ON_ONCE(ctx->num_exentries >= ctx->prog->aux->num_exentries))
  358. return -EINVAL;
  359. ex = &ctx->prog->aux->extable[ctx->num_exentries];
  360. pc = (unsigned long)&ctx->image[ctx->idx - 1];
  361. offset = pc - (long)&ex->insn;
  362. if (WARN_ON_ONCE(offset >= 0 || offset < INT_MIN))
  363. return -ERANGE;
  364. ex->insn = offset;
  365. /*
  366. * Since the extable follows the program, the fixup offset is always
  367. * negative and limited to BPF_JIT_REGION_SIZE. Store a positive value
  368. * to keep things simple, and put the destination register in the upper
  369. * bits. We don't need to worry about buildtime or runtime sort
  370. * modifying the upper bits because the table is already sorted, and
  371. * isn't part of the main exception table.
  372. */
  373. offset = (long)&ex->fixup - (pc + LOONGARCH_INSN_SIZE);
  374. if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, offset))
  375. return -ERANGE;
  376. ex->type = EX_TYPE_BPF;
  377. ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) | FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
  378. ctx->num_exentries++;
  379. return 0;
  380. }
  381. static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool extra_pass)
  382. {
  383. u8 tm = -1;
  384. u64 func_addr;
  385. bool func_addr_fixed, sign_extend;
  386. int i = insn - ctx->prog->insnsi;
  387. int ret, jmp_offset;
  388. const u8 code = insn->code;
  389. const u8 cond = BPF_OP(code);
  390. const u8 t1 = LOONGARCH_GPR_T1;
  391. const u8 t2 = LOONGARCH_GPR_T2;
  392. const u8 src = regmap[insn->src_reg];
  393. const u8 dst = regmap[insn->dst_reg];
  394. const s16 off = insn->off;
  395. const s32 imm = insn->imm;
  396. const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32;
  397. switch (code) {
  398. /* dst = src */
  399. case BPF_ALU | BPF_MOV | BPF_X:
  400. case BPF_ALU64 | BPF_MOV | BPF_X:
  401. switch (off) {
  402. case 0:
  403. move_reg(ctx, dst, src);
  404. emit_zext_32(ctx, dst, is32);
  405. break;
  406. case 8:
  407. move_reg(ctx, t1, src);
  408. emit_insn(ctx, extwb, dst, t1);
  409. emit_zext_32(ctx, dst, is32);
  410. break;
  411. case 16:
  412. move_reg(ctx, t1, src);
  413. emit_insn(ctx, extwh, dst, t1);
  414. emit_zext_32(ctx, dst, is32);
  415. break;
  416. case 32:
  417. emit_insn(ctx, addw, dst, src, LOONGARCH_GPR_ZERO);
  418. break;
  419. }
  420. break;
  421. /* dst = imm */
  422. case BPF_ALU | BPF_MOV | BPF_K:
  423. case BPF_ALU64 | BPF_MOV | BPF_K:
  424. move_imm(ctx, dst, imm, is32);
  425. break;
  426. /* dst = dst + src */
  427. case BPF_ALU | BPF_ADD | BPF_X:
  428. case BPF_ALU64 | BPF_ADD | BPF_X:
  429. emit_insn(ctx, addd, dst, dst, src);
  430. emit_zext_32(ctx, dst, is32);
  431. break;
  432. /* dst = dst + imm */
  433. case BPF_ALU | BPF_ADD | BPF_K:
  434. case BPF_ALU64 | BPF_ADD | BPF_K:
  435. if (is_signed_imm12(imm)) {
  436. emit_insn(ctx, addid, dst, dst, imm);
  437. } else {
  438. move_imm(ctx, t1, imm, is32);
  439. emit_insn(ctx, addd, dst, dst, t1);
  440. }
  441. emit_zext_32(ctx, dst, is32);
  442. break;
  443. /* dst = dst - src */
  444. case BPF_ALU | BPF_SUB | BPF_X:
  445. case BPF_ALU64 | BPF_SUB | BPF_X:
  446. emit_insn(ctx, subd, dst, dst, src);
  447. emit_zext_32(ctx, dst, is32);
  448. break;
  449. /* dst = dst - imm */
  450. case BPF_ALU | BPF_SUB | BPF_K:
  451. case BPF_ALU64 | BPF_SUB | BPF_K:
  452. if (is_signed_imm12(-imm)) {
  453. emit_insn(ctx, addid, dst, dst, -imm);
  454. } else {
  455. move_imm(ctx, t1, imm, is32);
  456. emit_insn(ctx, subd, dst, dst, t1);
  457. }
  458. emit_zext_32(ctx, dst, is32);
  459. break;
  460. /* dst = dst * src */
  461. case BPF_ALU | BPF_MUL | BPF_X:
  462. case BPF_ALU64 | BPF_MUL | BPF_X:
  463. emit_insn(ctx, muld, dst, dst, src);
  464. emit_zext_32(ctx, dst, is32);
  465. break;
  466. /* dst = dst * imm */
  467. case BPF_ALU | BPF_MUL | BPF_K:
  468. case BPF_ALU64 | BPF_MUL | BPF_K:
  469. move_imm(ctx, t1, imm, is32);
  470. emit_insn(ctx, muld, dst, dst, t1);
  471. emit_zext_32(ctx, dst, is32);
  472. break;
  473. /* dst = dst / src */
  474. case BPF_ALU | BPF_DIV | BPF_X:
  475. case BPF_ALU64 | BPF_DIV | BPF_X:
  476. if (!off) {
  477. emit_zext_32(ctx, dst, is32);
  478. move_reg(ctx, t1, src);
  479. emit_zext_32(ctx, t1, is32);
  480. emit_insn(ctx, divdu, dst, dst, t1);
  481. emit_zext_32(ctx, dst, is32);
  482. } else {
  483. emit_sext_32(ctx, dst, is32);
  484. move_reg(ctx, t1, src);
  485. emit_sext_32(ctx, t1, is32);
  486. emit_insn(ctx, divd, dst, dst, t1);
  487. emit_sext_32(ctx, dst, is32);
  488. }
  489. break;
  490. /* dst = dst / imm */
  491. case BPF_ALU | BPF_DIV | BPF_K:
  492. case BPF_ALU64 | BPF_DIV | BPF_K:
  493. if (!off) {
  494. move_imm(ctx, t1, imm, is32);
  495. emit_zext_32(ctx, dst, is32);
  496. emit_insn(ctx, divdu, dst, dst, t1);
  497. emit_zext_32(ctx, dst, is32);
  498. } else {
  499. move_imm(ctx, t1, imm, false);
  500. emit_sext_32(ctx, t1, is32);
  501. emit_sext_32(ctx, dst, is32);
  502. emit_insn(ctx, divd, dst, dst, t1);
  503. emit_sext_32(ctx, dst, is32);
  504. }
  505. break;
  506. /* dst = dst % src */
  507. case BPF_ALU | BPF_MOD | BPF_X:
  508. case BPF_ALU64 | BPF_MOD | BPF_X:
  509. if (!off) {
  510. emit_zext_32(ctx, dst, is32);
  511. move_reg(ctx, t1, src);
  512. emit_zext_32(ctx, t1, is32);
  513. emit_insn(ctx, moddu, dst, dst, t1);
  514. emit_zext_32(ctx, dst, is32);
  515. } else {
  516. emit_sext_32(ctx, dst, is32);
  517. move_reg(ctx, t1, src);
  518. emit_sext_32(ctx, t1, is32);
  519. emit_insn(ctx, modd, dst, dst, t1);
  520. emit_sext_32(ctx, dst, is32);
  521. }
  522. break;
  523. /* dst = dst % imm */
  524. case BPF_ALU | BPF_MOD | BPF_K:
  525. case BPF_ALU64 | BPF_MOD | BPF_K:
  526. if (!off) {
  527. move_imm(ctx, t1, imm, is32);
  528. emit_zext_32(ctx, dst, is32);
  529. emit_insn(ctx, moddu, dst, dst, t1);
  530. emit_zext_32(ctx, dst, is32);
  531. } else {
  532. move_imm(ctx, t1, imm, false);
  533. emit_sext_32(ctx, t1, is32);
  534. emit_sext_32(ctx, dst, is32);
  535. emit_insn(ctx, modd, dst, dst, t1);
  536. emit_sext_32(ctx, dst, is32);
  537. }
  538. break;
  539. /* dst = -dst */
  540. case BPF_ALU | BPF_NEG:
  541. case BPF_ALU64 | BPF_NEG:
  542. move_imm(ctx, t1, imm, is32);
  543. emit_insn(ctx, subd, dst, LOONGARCH_GPR_ZERO, dst);
  544. emit_zext_32(ctx, dst, is32);
  545. break;
  546. /* dst = dst & src */
  547. case BPF_ALU | BPF_AND | BPF_X:
  548. case BPF_ALU64 | BPF_AND | BPF_X:
  549. emit_insn(ctx, and, dst, dst, src);
  550. emit_zext_32(ctx, dst, is32);
  551. break;
  552. /* dst = dst & imm */
  553. case BPF_ALU | BPF_AND | BPF_K:
  554. case BPF_ALU64 | BPF_AND | BPF_K:
  555. if (is_unsigned_imm12(imm)) {
  556. emit_insn(ctx, andi, dst, dst, imm);
  557. } else {
  558. move_imm(ctx, t1, imm, is32);
  559. emit_insn(ctx, and, dst, dst, t1);
  560. }
  561. emit_zext_32(ctx, dst, is32);
  562. break;
  563. /* dst = dst | src */
  564. case BPF_ALU | BPF_OR | BPF_X:
  565. case BPF_ALU64 | BPF_OR | BPF_X:
  566. emit_insn(ctx, or, dst, dst, src);
  567. emit_zext_32(ctx, dst, is32);
  568. break;
  569. /* dst = dst | imm */
  570. case BPF_ALU | BPF_OR | BPF_K:
  571. case BPF_ALU64 | BPF_OR | BPF_K:
  572. if (is_unsigned_imm12(imm)) {
  573. emit_insn(ctx, ori, dst, dst, imm);
  574. } else {
  575. move_imm(ctx, t1, imm, is32);
  576. emit_insn(ctx, or, dst, dst, t1);
  577. }
  578. emit_zext_32(ctx, dst, is32);
  579. break;
  580. /* dst = dst ^ src */
  581. case BPF_ALU | BPF_XOR | BPF_X:
  582. case BPF_ALU64 | BPF_XOR | BPF_X:
  583. emit_insn(ctx, xor, dst, dst, src);
  584. emit_zext_32(ctx, dst, is32);
  585. break;
  586. /* dst = dst ^ imm */
  587. case BPF_ALU | BPF_XOR | BPF_K:
  588. case BPF_ALU64 | BPF_XOR | BPF_K:
  589. if (is_unsigned_imm12(imm)) {
  590. emit_insn(ctx, xori, dst, dst, imm);
  591. } else {
  592. move_imm(ctx, t1, imm, is32);
  593. emit_insn(ctx, xor, dst, dst, t1);
  594. }
  595. emit_zext_32(ctx, dst, is32);
  596. break;
  597. /* dst = dst << src (logical) */
  598. case BPF_ALU | BPF_LSH | BPF_X:
  599. emit_insn(ctx, sllw, dst, dst, src);
  600. emit_zext_32(ctx, dst, is32);
  601. break;
  602. case BPF_ALU64 | BPF_LSH | BPF_X:
  603. emit_insn(ctx, slld, dst, dst, src);
  604. break;
  605. /* dst = dst << imm (logical) */
  606. case BPF_ALU | BPF_LSH | BPF_K:
  607. emit_insn(ctx, slliw, dst, dst, imm);
  608. emit_zext_32(ctx, dst, is32);
  609. break;
  610. case BPF_ALU64 | BPF_LSH | BPF_K:
  611. emit_insn(ctx, sllid, dst, dst, imm);
  612. break;
  613. /* dst = dst >> src (logical) */
  614. case BPF_ALU | BPF_RSH | BPF_X:
  615. emit_insn(ctx, srlw, dst, dst, src);
  616. emit_zext_32(ctx, dst, is32);
  617. break;
  618. case BPF_ALU64 | BPF_RSH | BPF_X:
  619. emit_insn(ctx, srld, dst, dst, src);
  620. break;
  621. /* dst = dst >> imm (logical) */
  622. case BPF_ALU | BPF_RSH | BPF_K:
  623. emit_insn(ctx, srliw, dst, dst, imm);
  624. emit_zext_32(ctx, dst, is32);
  625. break;
  626. case BPF_ALU64 | BPF_RSH | BPF_K:
  627. emit_insn(ctx, srlid, dst, dst, imm);
  628. break;
  629. /* dst = dst >> src (arithmetic) */
  630. case BPF_ALU | BPF_ARSH | BPF_X:
  631. emit_insn(ctx, sraw, dst, dst, src);
  632. emit_zext_32(ctx, dst, is32);
  633. break;
  634. case BPF_ALU64 | BPF_ARSH | BPF_X:
  635. emit_insn(ctx, srad, dst, dst, src);
  636. break;
  637. /* dst = dst >> imm (arithmetic) */
  638. case BPF_ALU | BPF_ARSH | BPF_K:
  639. emit_insn(ctx, sraiw, dst, dst, imm);
  640. emit_zext_32(ctx, dst, is32);
  641. break;
  642. case BPF_ALU64 | BPF_ARSH | BPF_K:
  643. emit_insn(ctx, sraid, dst, dst, imm);
  644. break;
  645. /* dst = BSWAP##imm(dst) */
  646. case BPF_ALU | BPF_END | BPF_FROM_LE:
  647. switch (imm) {
  648. case 16:
  649. /* zero-extend 16 bits into 64 bits */
  650. emit_insn(ctx, bstrpickd, dst, dst, 15, 0);
  651. break;
  652. case 32:
  653. /* zero-extend 32 bits into 64 bits */
  654. emit_zext_32(ctx, dst, is32);
  655. break;
  656. case 64:
  657. /* do nothing */
  658. break;
  659. }
  660. break;
  661. case BPF_ALU | BPF_END | BPF_FROM_BE:
  662. case BPF_ALU64 | BPF_END | BPF_FROM_LE:
  663. switch (imm) {
  664. case 16:
  665. emit_insn(ctx, revb2h, dst, dst);
  666. /* zero-extend 16 bits into 64 bits */
  667. emit_insn(ctx, bstrpickd, dst, dst, 15, 0);
  668. break;
  669. case 32:
  670. emit_insn(ctx, revb2w, dst, dst);
  671. /* clear the upper 32 bits */
  672. emit_zext_32(ctx, dst, true);
  673. break;
  674. case 64:
  675. emit_insn(ctx, revbd, dst, dst);
  676. break;
  677. }
  678. break;
  679. /* PC += off if dst cond src */
  680. case BPF_JMP | BPF_JEQ | BPF_X:
  681. case BPF_JMP | BPF_JNE | BPF_X:
  682. case BPF_JMP | BPF_JGT | BPF_X:
  683. case BPF_JMP | BPF_JGE | BPF_X:
  684. case BPF_JMP | BPF_JLT | BPF_X:
  685. case BPF_JMP | BPF_JLE | BPF_X:
  686. case BPF_JMP | BPF_JSGT | BPF_X:
  687. case BPF_JMP | BPF_JSGE | BPF_X:
  688. case BPF_JMP | BPF_JSLT | BPF_X:
  689. case BPF_JMP | BPF_JSLE | BPF_X:
  690. case BPF_JMP32 | BPF_JEQ | BPF_X:
  691. case BPF_JMP32 | BPF_JNE | BPF_X:
  692. case BPF_JMP32 | BPF_JGT | BPF_X:
  693. case BPF_JMP32 | BPF_JGE | BPF_X:
  694. case BPF_JMP32 | BPF_JLT | BPF_X:
  695. case BPF_JMP32 | BPF_JLE | BPF_X:
  696. case BPF_JMP32 | BPF_JSGT | BPF_X:
  697. case BPF_JMP32 | BPF_JSGE | BPF_X:
  698. case BPF_JMP32 | BPF_JSLT | BPF_X:
  699. case BPF_JMP32 | BPF_JSLE | BPF_X:
  700. jmp_offset = bpf2la_offset(i, off, ctx);
  701. move_reg(ctx, t1, dst);
  702. move_reg(ctx, t2, src);
  703. if (is_signed_bpf_cond(BPF_OP(code))) {
  704. emit_sext_32(ctx, t1, is32);
  705. emit_sext_32(ctx, t2, is32);
  706. } else {
  707. emit_zext_32(ctx, t1, is32);
  708. emit_zext_32(ctx, t2, is32);
  709. }
  710. if (emit_cond_jmp(ctx, cond, t1, t2, jmp_offset) < 0)
  711. goto toofar;
  712. break;
  713. /* PC += off if dst cond imm */
  714. case BPF_JMP | BPF_JEQ | BPF_K:
  715. case BPF_JMP | BPF_JNE | BPF_K:
  716. case BPF_JMP | BPF_JGT | BPF_K:
  717. case BPF_JMP | BPF_JGE | BPF_K:
  718. case BPF_JMP | BPF_JLT | BPF_K:
  719. case BPF_JMP | BPF_JLE | BPF_K:
  720. case BPF_JMP | BPF_JSGT | BPF_K:
  721. case BPF_JMP | BPF_JSGE | BPF_K:
  722. case BPF_JMP | BPF_JSLT | BPF_K:
  723. case BPF_JMP | BPF_JSLE | BPF_K:
  724. case BPF_JMP32 | BPF_JEQ | BPF_K:
  725. case BPF_JMP32 | BPF_JNE | BPF_K:
  726. case BPF_JMP32 | BPF_JGT | BPF_K:
  727. case BPF_JMP32 | BPF_JGE | BPF_K:
  728. case BPF_JMP32 | BPF_JLT | BPF_K:
  729. case BPF_JMP32 | BPF_JLE | BPF_K:
  730. case BPF_JMP32 | BPF_JSGT | BPF_K:
  731. case BPF_JMP32 | BPF_JSGE | BPF_K:
  732. case BPF_JMP32 | BPF_JSLT | BPF_K:
  733. case BPF_JMP32 | BPF_JSLE | BPF_K:
  734. jmp_offset = bpf2la_offset(i, off, ctx);
  735. if (imm) {
  736. move_imm(ctx, t1, imm, false);
  737. tm = t1;
  738. } else {
  739. /* If imm is 0, simply use zero register. */
  740. tm = LOONGARCH_GPR_ZERO;
  741. }
  742. move_reg(ctx, t2, dst);
  743. if (is_signed_bpf_cond(BPF_OP(code))) {
  744. emit_sext_32(ctx, tm, is32);
  745. emit_sext_32(ctx, t2, is32);
  746. } else {
  747. emit_zext_32(ctx, tm, is32);
  748. emit_zext_32(ctx, t2, is32);
  749. }
  750. if (emit_cond_jmp(ctx, cond, t2, tm, jmp_offset) < 0)
  751. goto toofar;
  752. break;
  753. /* PC += off if dst & src */
  754. case BPF_JMP | BPF_JSET | BPF_X:
  755. case BPF_JMP32 | BPF_JSET | BPF_X:
  756. jmp_offset = bpf2la_offset(i, off, ctx);
  757. emit_insn(ctx, and, t1, dst, src);
  758. emit_zext_32(ctx, t1, is32);
  759. if (emit_cond_jmp(ctx, cond, t1, LOONGARCH_GPR_ZERO, jmp_offset) < 0)
  760. goto toofar;
  761. break;
  762. /* PC += off if dst & imm */
  763. case BPF_JMP | BPF_JSET | BPF_K:
  764. case BPF_JMP32 | BPF_JSET | BPF_K:
  765. jmp_offset = bpf2la_offset(i, off, ctx);
  766. move_imm(ctx, t1, imm, is32);
  767. emit_insn(ctx, and, t1, dst, t1);
  768. emit_zext_32(ctx, t1, is32);
  769. if (emit_cond_jmp(ctx, cond, t1, LOONGARCH_GPR_ZERO, jmp_offset) < 0)
  770. goto toofar;
  771. break;
  772. /* PC += off */
  773. case BPF_JMP | BPF_JA:
  774. case BPF_JMP32 | BPF_JA:
  775. if (BPF_CLASS(code) == BPF_JMP)
  776. jmp_offset = bpf2la_offset(i, off, ctx);
  777. else
  778. jmp_offset = bpf2la_offset(i, imm, ctx);
  779. if (emit_uncond_jmp(ctx, jmp_offset) < 0)
  780. goto toofar;
  781. break;
  782. /* function call */
  783. case BPF_JMP | BPF_CALL:
  784. mark_call(ctx);
  785. ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
  786. &func_addr, &func_addr_fixed);
  787. if (ret < 0)
  788. return ret;
  789. move_addr(ctx, t1, func_addr);
  790. emit_insn(ctx, jirl, LOONGARCH_GPR_RA, t1, 0);
  791. if (insn->src_reg != BPF_PSEUDO_CALL)
  792. move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0);
  793. break;
  794. /* tail call */
  795. case BPF_JMP | BPF_TAIL_CALL:
  796. mark_tail_call(ctx);
  797. if (emit_bpf_tail_call(ctx, i) < 0)
  798. return -EINVAL;
  799. break;
  800. /* function return */
  801. case BPF_JMP | BPF_EXIT:
  802. if (i == ctx->prog->len - 1)
  803. break;
  804. jmp_offset = epilogue_offset(ctx);
  805. if (emit_uncond_jmp(ctx, jmp_offset) < 0)
  806. goto toofar;
  807. break;
  808. /* dst = imm64 */
  809. case BPF_LD | BPF_IMM | BPF_DW:
  810. {
  811. const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm;
  812. if (bpf_pseudo_func(insn))
  813. move_addr(ctx, dst, imm64);
  814. else
  815. move_imm(ctx, dst, imm64, is32);
  816. return 1;
  817. }
  818. /* dst = *(size *)(src + off) */
  819. case BPF_LDX | BPF_MEM | BPF_B:
  820. case BPF_LDX | BPF_MEM | BPF_H:
  821. case BPF_LDX | BPF_MEM | BPF_W:
  822. case BPF_LDX | BPF_MEM | BPF_DW:
  823. case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
  824. case BPF_LDX | BPF_PROBE_MEM | BPF_W:
  825. case BPF_LDX | BPF_PROBE_MEM | BPF_H:
  826. case BPF_LDX | BPF_PROBE_MEM | BPF_B:
  827. /* dst_reg = (s64)*(signed size *)(src_reg + off) */
  828. case BPF_LDX | BPF_MEMSX | BPF_B:
  829. case BPF_LDX | BPF_MEMSX | BPF_H:
  830. case BPF_LDX | BPF_MEMSX | BPF_W:
  831. case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
  832. case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
  833. case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
  834. sign_extend = BPF_MODE(insn->code) == BPF_MEMSX ||
  835. BPF_MODE(insn->code) == BPF_PROBE_MEMSX;
  836. switch (BPF_SIZE(code)) {
  837. case BPF_B:
  838. if (is_signed_imm12(off)) {
  839. if (sign_extend)
  840. emit_insn(ctx, ldb, dst, src, off);
  841. else
  842. emit_insn(ctx, ldbu, dst, src, off);
  843. } else {
  844. move_imm(ctx, t1, off, is32);
  845. if (sign_extend)
  846. emit_insn(ctx, ldxb, dst, src, t1);
  847. else
  848. emit_insn(ctx, ldxbu, dst, src, t1);
  849. }
  850. break;
  851. case BPF_H:
  852. if (is_signed_imm12(off)) {
  853. if (sign_extend)
  854. emit_insn(ctx, ldh, dst, src, off);
  855. else
  856. emit_insn(ctx, ldhu, dst, src, off);
  857. } else {
  858. move_imm(ctx, t1, off, is32);
  859. if (sign_extend)
  860. emit_insn(ctx, ldxh, dst, src, t1);
  861. else
  862. emit_insn(ctx, ldxhu, dst, src, t1);
  863. }
  864. break;
  865. case BPF_W:
  866. if (is_signed_imm12(off)) {
  867. if (sign_extend)
  868. emit_insn(ctx, ldw, dst, src, off);
  869. else
  870. emit_insn(ctx, ldwu, dst, src, off);
  871. } else {
  872. move_imm(ctx, t1, off, is32);
  873. if (sign_extend)
  874. emit_insn(ctx, ldxw, dst, src, t1);
  875. else
  876. emit_insn(ctx, ldxwu, dst, src, t1);
  877. }
  878. break;
  879. case BPF_DW:
  880. move_imm(ctx, t1, off, is32);
  881. emit_insn(ctx, ldxd, dst, src, t1);
  882. break;
  883. }
  884. ret = add_exception_handler(insn, ctx, dst);
  885. if (ret)
  886. return ret;
  887. break;
  888. /* *(size *)(dst + off) = imm */
  889. case BPF_ST | BPF_MEM | BPF_B:
  890. case BPF_ST | BPF_MEM | BPF_H:
  891. case BPF_ST | BPF_MEM | BPF_W:
  892. case BPF_ST | BPF_MEM | BPF_DW:
  893. switch (BPF_SIZE(code)) {
  894. case BPF_B:
  895. move_imm(ctx, t1, imm, is32);
  896. if (is_signed_imm12(off)) {
  897. emit_insn(ctx, stb, t1, dst, off);
  898. } else {
  899. move_imm(ctx, t2, off, is32);
  900. emit_insn(ctx, stxb, t1, dst, t2);
  901. }
  902. break;
  903. case BPF_H:
  904. move_imm(ctx, t1, imm, is32);
  905. if (is_signed_imm12(off)) {
  906. emit_insn(ctx, sth, t1, dst, off);
  907. } else {
  908. move_imm(ctx, t2, off, is32);
  909. emit_insn(ctx, stxh, t1, dst, t2);
  910. }
  911. break;
  912. case BPF_W:
  913. move_imm(ctx, t1, imm, is32);
  914. if (is_signed_imm12(off)) {
  915. emit_insn(ctx, stw, t1, dst, off);
  916. } else if (is_signed_imm14(off)) {
  917. emit_insn(ctx, stptrw, t1, dst, off);
  918. } else {
  919. move_imm(ctx, t2, off, is32);
  920. emit_insn(ctx, stxw, t1, dst, t2);
  921. }
  922. break;
  923. case BPF_DW:
  924. move_imm(ctx, t1, imm, is32);
  925. if (is_signed_imm12(off)) {
  926. emit_insn(ctx, std, t1, dst, off);
  927. } else if (is_signed_imm14(off)) {
  928. emit_insn(ctx, stptrd, t1, dst, off);
  929. } else {
  930. move_imm(ctx, t2, off, is32);
  931. emit_insn(ctx, stxd, t1, dst, t2);
  932. }
  933. break;
  934. }
  935. break;
  936. /* *(size *)(dst + off) = src */
  937. case BPF_STX | BPF_MEM | BPF_B:
  938. case BPF_STX | BPF_MEM | BPF_H:
  939. case BPF_STX | BPF_MEM | BPF_W:
  940. case BPF_STX | BPF_MEM | BPF_DW:
  941. switch (BPF_SIZE(code)) {
  942. case BPF_B:
  943. if (is_signed_imm12(off)) {
  944. emit_insn(ctx, stb, src, dst, off);
  945. } else {
  946. move_imm(ctx, t1, off, is32);
  947. emit_insn(ctx, stxb, src, dst, t1);
  948. }
  949. break;
  950. case BPF_H:
  951. if (is_signed_imm12(off)) {
  952. emit_insn(ctx, sth, src, dst, off);
  953. } else {
  954. move_imm(ctx, t1, off, is32);
  955. emit_insn(ctx, stxh, src, dst, t1);
  956. }
  957. break;
  958. case BPF_W:
  959. if (is_signed_imm12(off)) {
  960. emit_insn(ctx, stw, src, dst, off);
  961. } else if (is_signed_imm14(off)) {
  962. emit_insn(ctx, stptrw, src, dst, off);
  963. } else {
  964. move_imm(ctx, t1, off, is32);
  965. emit_insn(ctx, stxw, src, dst, t1);
  966. }
  967. break;
  968. case BPF_DW:
  969. if (is_signed_imm12(off)) {
  970. emit_insn(ctx, std, src, dst, off);
  971. } else if (is_signed_imm14(off)) {
  972. emit_insn(ctx, stptrd, src, dst, off);
  973. } else {
  974. move_imm(ctx, t1, off, is32);
  975. emit_insn(ctx, stxd, src, dst, t1);
  976. }
  977. break;
  978. }
  979. break;
  980. case BPF_STX | BPF_ATOMIC | BPF_W:
  981. case BPF_STX | BPF_ATOMIC | BPF_DW:
  982. emit_atomic(insn, ctx);
  983. break;
  984. /* Speculation barrier */
  985. case BPF_ST | BPF_NOSPEC:
  986. break;
  987. default:
  988. pr_err("bpf_jit: unknown opcode %02x\n", code);
  989. return -EINVAL;
  990. }
  991. return 0;
  992. toofar:
  993. pr_info_once("bpf_jit: opcode %02x, jump too far\n", code);
  994. return -E2BIG;
  995. }
  996. static int build_body(struct jit_ctx *ctx, bool extra_pass)
  997. {
  998. int i;
  999. const struct bpf_prog *prog = ctx->prog;
  1000. for (i = 0; i < prog->len; i++) {
  1001. const struct bpf_insn *insn = &prog->insnsi[i];
  1002. int ret;
  1003. if (ctx->image == NULL)
  1004. ctx->offset[i] = ctx->idx;
  1005. ret = build_insn(insn, ctx, extra_pass);
  1006. if (ret > 0) {
  1007. i++;
  1008. if (ctx->image == NULL)
  1009. ctx->offset[i] = ctx->idx;
  1010. continue;
  1011. }
  1012. if (ret)
  1013. return ret;
  1014. }
  1015. if (ctx->image == NULL)
  1016. ctx->offset[i] = ctx->idx;
  1017. return 0;
  1018. }
  1019. /* Fill space with break instructions */
  1020. static void jit_fill_hole(void *area, unsigned int size)
  1021. {
  1022. u32 *ptr;
  1023. /* We are guaranteed to have aligned memory */
  1024. for (ptr = area; size >= sizeof(u32); size -= sizeof(u32))
  1025. *ptr++ = INSN_BREAK;
  1026. }
  1027. static int validate_code(struct jit_ctx *ctx)
  1028. {
  1029. int i;
  1030. union loongarch_instruction insn;
  1031. for (i = 0; i < ctx->idx; i++) {
  1032. insn = ctx->image[i];
  1033. /* Check INSN_BREAK */
  1034. if (insn.word == INSN_BREAK)
  1035. return -1;
  1036. }
  1037. if (WARN_ON_ONCE(ctx->num_exentries != ctx->prog->aux->num_exentries))
  1038. return -1;
  1039. return 0;
  1040. }
  1041. struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
  1042. {
  1043. bool tmp_blinded = false, extra_pass = false;
  1044. u8 *image_ptr;
  1045. int image_size, prog_size, extable_size;
  1046. struct jit_ctx ctx;
  1047. struct jit_data *jit_data;
  1048. struct bpf_binary_header *header;
  1049. struct bpf_prog *tmp, *orig_prog = prog;
  1050. /*
  1051. * If BPF JIT was not enabled then we must fall back to
  1052. * the interpreter.
  1053. */
  1054. if (!prog->jit_requested)
  1055. return orig_prog;
  1056. tmp = bpf_jit_blind_constants(prog);
  1057. /*
  1058. * If blinding was requested and we failed during blinding,
  1059. * we must fall back to the interpreter. Otherwise, we save
  1060. * the new JITed code.
  1061. */
  1062. if (IS_ERR(tmp))
  1063. return orig_prog;
  1064. if (tmp != prog) {
  1065. tmp_blinded = true;
  1066. prog = tmp;
  1067. }
  1068. jit_data = prog->aux->jit_data;
  1069. if (!jit_data) {
  1070. jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL);
  1071. if (!jit_data) {
  1072. prog = orig_prog;
  1073. goto out;
  1074. }
  1075. prog->aux->jit_data = jit_data;
  1076. }
  1077. if (jit_data->ctx.offset) {
  1078. ctx = jit_data->ctx;
  1079. image_ptr = jit_data->image;
  1080. header = jit_data->header;
  1081. extra_pass = true;
  1082. prog_size = sizeof(u32) * ctx.idx;
  1083. goto skip_init_ctx;
  1084. }
  1085. memset(&ctx, 0, sizeof(ctx));
  1086. ctx.prog = prog;
  1087. ctx.offset = kvcalloc(prog->len + 1, sizeof(u32), GFP_KERNEL);
  1088. if (ctx.offset == NULL) {
  1089. prog = orig_prog;
  1090. goto out_offset;
  1091. }
  1092. /* 1. Initial fake pass to compute ctx->idx and set ctx->flags */
  1093. build_prologue(&ctx);
  1094. if (build_body(&ctx, extra_pass)) {
  1095. prog = orig_prog;
  1096. goto out_offset;
  1097. }
  1098. ctx.epilogue_offset = ctx.idx;
  1099. build_epilogue(&ctx);
  1100. extable_size = prog->aux->num_exentries * sizeof(struct exception_table_entry);
  1101. /* Now we know the actual image size.
  1102. * As each LoongArch instruction is of length 32bit,
  1103. * we are translating number of JITed intructions into
  1104. * the size required to store these JITed code.
  1105. */
  1106. prog_size = sizeof(u32) * ctx.idx;
  1107. image_size = prog_size + extable_size;
  1108. /* Now we know the size of the structure to make */
  1109. header = bpf_jit_binary_alloc(image_size, &image_ptr,
  1110. sizeof(u32), jit_fill_hole);
  1111. if (header == NULL) {
  1112. prog = orig_prog;
  1113. goto out_offset;
  1114. }
  1115. /* 2. Now, the actual pass to generate final JIT code */
  1116. ctx.image = (union loongarch_instruction *)image_ptr;
  1117. if (extable_size)
  1118. prog->aux->extable = (void *)image_ptr + prog_size;
  1119. skip_init_ctx:
  1120. ctx.idx = 0;
  1121. ctx.num_exentries = 0;
  1122. build_prologue(&ctx);
  1123. if (build_body(&ctx, extra_pass)) {
  1124. bpf_jit_binary_free(header);
  1125. prog = orig_prog;
  1126. goto out_offset;
  1127. }
  1128. build_epilogue(&ctx);
  1129. /* 3. Extra pass to validate JITed code */
  1130. if (validate_code(&ctx)) {
  1131. bpf_jit_binary_free(header);
  1132. prog = orig_prog;
  1133. goto out_offset;
  1134. }
  1135. /* And we're done */
  1136. if (bpf_jit_enable > 1)
  1137. bpf_jit_dump(prog->len, prog_size, 2, ctx.image);
  1138. /* Update the icache */
  1139. flush_icache_range((unsigned long)header, (unsigned long)(ctx.image + ctx.idx));
  1140. if (!prog->is_func || extra_pass) {
  1141. int err;
  1142. if (extra_pass && ctx.idx != jit_data->ctx.idx) {
  1143. pr_err_once("multi-func JIT bug %d != %d\n",
  1144. ctx.idx, jit_data->ctx.idx);
  1145. goto out_free;
  1146. }
  1147. err = bpf_jit_binary_lock_ro(header);
  1148. if (err) {
  1149. pr_err_once("bpf_jit_binary_lock_ro() returned %d\n",
  1150. err);
  1151. goto out_free;
  1152. }
  1153. } else {
  1154. jit_data->ctx = ctx;
  1155. jit_data->image = image_ptr;
  1156. jit_data->header = header;
  1157. }
  1158. prog->jited = 1;
  1159. prog->jited_len = prog_size;
  1160. prog->bpf_func = (void *)ctx.image;
  1161. if (!prog->is_func || extra_pass) {
  1162. int i;
  1163. /* offset[prog->len] is the size of program */
  1164. for (i = 0; i <= prog->len; i++)
  1165. ctx.offset[i] *= LOONGARCH_INSN_SIZE;
  1166. bpf_prog_fill_jited_linfo(prog, ctx.offset + 1);
  1167. out_offset:
  1168. kvfree(ctx.offset);
  1169. kfree(jit_data);
  1170. prog->aux->jit_data = NULL;
  1171. }
  1172. out:
  1173. if (tmp_blinded)
  1174. bpf_jit_prog_release_other(prog, prog == orig_prog ? tmp : orig_prog);
  1175. return prog;
  1176. out_free:
  1177. bpf_jit_binary_free(header);
  1178. prog->bpf_func = NULL;
  1179. prog->jited = 0;
  1180. prog->jited_len = 0;
  1181. goto out_offset;
  1182. }
  1183. /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
  1184. bool bpf_jit_supports_subprog_tailcalls(void)
  1185. {
  1186. return true;
  1187. }