aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/net/bpf_jit_comp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/net/bpf_jit_comp.c')
-rw-r--r--arch/x86/net/bpf_jit_comp.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 5a5b6e4dd738..0597f95b6da6 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -30,7 +30,10 @@ int bpf_jit_enable __read_mostly;
30 * assembly code in arch/x86/net/bpf_jit.S 30 * assembly code in arch/x86/net/bpf_jit.S
31 */ 31 */
32extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; 32extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
33extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[]; 33extern u8 sk_load_word_positive_offset[], sk_load_half_positive_offset[];
34extern u8 sk_load_byte_positive_offset[], sk_load_byte_msh_positive_offset[];
35extern u8 sk_load_word_negative_offset[], sk_load_half_negative_offset[];
36extern u8 sk_load_byte_negative_offset[], sk_load_byte_msh_negative_offset[];
34 37
35static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) 38static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
36{ 39{
@@ -117,6 +120,8 @@ static inline void bpf_flush_icache(void *start, void *end)
117 set_fs(old_fs); 120 set_fs(old_fs);
118} 121}
119 122
123#define CHOOSE_LOAD_FUNC(K, func) \
124 ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
120 125
121void bpf_jit_compile(struct sk_filter *fp) 126void bpf_jit_compile(struct sk_filter *fp)
122{ 127{
@@ -473,44 +478,46 @@ void bpf_jit_compile(struct sk_filter *fp)
473#endif 478#endif
474 break; 479 break;
475 case BPF_S_LD_W_ABS: 480 case BPF_S_LD_W_ABS:
476 func = sk_load_word; 481 func = CHOOSE_LOAD_FUNC(K, sk_load_word);
477common_load: seen |= SEEN_DATAREF; 482common_load: seen |= SEEN_DATAREF;
478 if ((int)K < 0) {
479 /* Abort the JIT because __load_pointer() is needed. */
480 goto out;
481 }
482 t_offset = func - (image + addrs[i]); 483 t_offset = func - (image + addrs[i]);
483 EMIT1_off32(0xbe, K); /* mov imm32,%esi */ 484 EMIT1_off32(0xbe, K); /* mov imm32,%esi */
484 EMIT1_off32(0xe8, t_offset); /* call */ 485 EMIT1_off32(0xe8, t_offset); /* call */
485 break; 486 break;
486 case BPF_S_LD_H_ABS: 487 case BPF_S_LD_H_ABS:
487 func = sk_load_half; 488 func = CHOOSE_LOAD_FUNC(K, sk_load_half);
488 goto common_load; 489 goto common_load;
489 case BPF_S_LD_B_ABS: 490 case BPF_S_LD_B_ABS:
490 func = sk_load_byte; 491 func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
491 goto common_load; 492 goto common_load;
492 case BPF_S_LDX_B_MSH: 493 case BPF_S_LDX_B_MSH:
493 if ((int)K < 0) { 494 func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
494 /* Abort the JIT because __load_pointer() is needed. */
495 goto out;
496 }
497 seen |= SEEN_DATAREF | SEEN_XREG; 495 seen |= SEEN_DATAREF | SEEN_XREG;
498 t_offset = sk_load_byte_msh - (image + addrs[i]); 496 t_offset = func - (image + addrs[i]);
499 EMIT1_off32(0xbe, K); /* mov imm32,%esi */ 497 EMIT1_off32(0xbe, K); /* mov imm32,%esi */
500 EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */ 498 EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */
501 break; 499 break;
502 case BPF_S_LD_W_IND: 500 case BPF_S_LD_W_IND:
503 func = sk_load_word_ind; 501 func = sk_load_word;
504common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG; 502common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
505 t_offset = func - (image + addrs[i]); 503 t_offset = func - (image + addrs[i]);
506 EMIT1_off32(0xbe, K); /* mov imm32,%esi */ 504 if (K) {
505 if (is_imm8(K)) {
506 EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */
507 } else {
508 EMIT2(0x8d, 0xb3); /* lea imm32(%rbx),%esi */
509 EMIT(K, 4);
510 }
511 } else {
512 EMIT2(0x89,0xde); /* mov %ebx,%esi */
513 }
507 EMIT1_off32(0xe8, t_offset); /* call sk_load_xxx_ind */ 514 EMIT1_off32(0xe8, t_offset); /* call sk_load_xxx_ind */
508 break; 515 break;
509 case BPF_S_LD_H_IND: 516 case BPF_S_LD_H_IND:
510 func = sk_load_half_ind; 517 func = sk_load_half;
511 goto common_load_ind; 518 goto common_load_ind;
512 case BPF_S_LD_B_IND: 519 case BPF_S_LD_B_IND:
513 func = sk_load_byte_ind; 520 func = sk_load_byte;
514 goto common_load_ind; 521 goto common_load_ind;
515 case BPF_S_JMP_JA: 522 case BPF_S_JMP_JA:
516 t_offset = addrs[i + K] - addrs[i]; 523 t_offset = addrs[i + K] - addrs[i];