Skip to content

Commit 4071bd8

Browse files
committed
Merge branch 'bpf-MIPS-infra'
David Daney says: ==================== bpf: Changes needed (or desired) for MIPS support This is a grab bag of changes to the bpf testing infrastructure I developed working on MIPS eBPF JIT support. The change to bpf_jit_disasm is probably universally beneficial, the others are more MIPS specific. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 2fae5d0 + 4b7190e commit 4071bd8

File tree

6 files changed

+104
-14
lines changed

6 files changed

+104
-14
lines changed

lib/test_bpf.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,30 @@ static int bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
435435
return 0;
436436
}
437437

438+
static int bpf_fill_jump_around_ld_abs(struct bpf_test *self)
439+
{
440+
unsigned int len = BPF_MAXINSNS;
441+
struct bpf_insn *insn;
442+
int i = 0;
443+
444+
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
445+
if (!insn)
446+
return -ENOMEM;
447+
448+
insn[i++] = BPF_MOV64_REG(R6, R1);
449+
insn[i++] = BPF_LD_ABS(BPF_B, 0);
450+
insn[i] = BPF_JMP_IMM(BPF_JEQ, R0, 10, len - i - 2);
451+
i++;
452+
while (i < len - 1)
453+
insn[i++] = BPF_LD_ABS(BPF_B, 1);
454+
insn[i] = BPF_EXIT_INSN();
455+
456+
self->u.ptr.insns = insn;
457+
self->u.ptr.len = len;
458+
459+
return 0;
460+
}
461+
438462
static int __bpf_fill_stxdw(struct bpf_test *self, int size)
439463
{
440464
unsigned int len = BPF_MAXINSNS;
@@ -5044,6 +5068,14 @@ static struct bpf_test tests[] = {
50445068
{ { ETH_HLEN, 0xbef } },
50455069
.fill_helper = bpf_fill_ld_abs_vlan_push_pop,
50465070
},
5071+
{
5072+
"BPF_MAXINSNS: jump around ld_abs",
5073+
{ },
5074+
INTERNAL,
5075+
{ 10, 11 },
5076+
{ { 2, 10 } },
5077+
.fill_helper = bpf_fill_jump_around_ld_abs,
5078+
},
50475079
/*
50485080
* LD_IND / LD_ABS on fragmented SKBs
50495081
*/

samples/bpf/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,17 @@ clean:
160160
$(MAKE) -C ../../ M=$(CURDIR) clean
161161
@rm -f *~
162162

163+
$(obj)/syscall_nrs.s: $(src)/syscall_nrs.c
164+
$(call if_changed_dep,cc_s_c)
165+
166+
$(obj)/syscall_nrs.h: $(obj)/syscall_nrs.s FORCE
167+
$(call filechk,offsets,__SYSCALL_NRS_H__)
168+
169+
clean-files += syscall_nrs.h
170+
171+
FORCE:
172+
173+
163174
# Verify LLVM compiler tools are available and bpf target is supported by llc
164175
.PHONY: verify_cmds verify_target_bpf $(CLANG) $(LLC)
165176

@@ -180,6 +191,8 @@ verify_target_bpf: verify_cmds
180191

181192
$(src)/*.c: verify_target_bpf
182193

194+
$(obj)/tracex5_kern.o: $(obj)/syscall_nrs.h
195+
183196
# asm/sysreg.h - inline assembly used by it is incompatible with llvm.
184197
# But, there is no easy way to fix it, so just exclude it since it is
185198
# useless for BPF samples.

samples/bpf/bpf_helpers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,19 @@ static int (*bpf_skb_change_head)(void *, int len, int flags) =
136136
#define PT_REGS_SP(x) ((x)->sp)
137137
#define PT_REGS_IP(x) ((x)->pc)
138138

139+
#elif defined(__mips__)
140+
141+
#define PT_REGS_PARM1(x) ((x)->regs[4])
142+
#define PT_REGS_PARM2(x) ((x)->regs[5])
143+
#define PT_REGS_PARM3(x) ((x)->regs[6])
144+
#define PT_REGS_PARM4(x) ((x)->regs[7])
145+
#define PT_REGS_PARM5(x) ((x)->regs[8])
146+
#define PT_REGS_RET(x) ((x)->regs[31])
147+
#define PT_REGS_FP(x) ((x)->regs[30]) /* Works only with CONFIG_FRAME_POINTER */
148+
#define PT_REGS_RC(x) ((x)->regs[1])
149+
#define PT_REGS_SP(x) ((x)->regs[29])
150+
#define PT_REGS_IP(x) ((x)->cp0_epc)
151+
139152
#elif defined(__powerpc__)
140153

141154
#define PT_REGS_PARM1(x) ((x)->gpr[3])

samples/bpf/syscall_nrs.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <uapi/linux/unistd.h>
2+
#include <linux/kbuild.h>
3+
4+
#define SYSNR(_NR) DEFINE(SYS ## _NR, _NR)
5+
6+
void syscall_defines(void)
7+
{
8+
COMMENT("Linux system call numbers.");
9+
SYSNR(__NR_write);
10+
SYSNR(__NR_read);
11+
SYSNR(__NR_mmap);
12+
}

samples/bpf/tracex5_kern.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <uapi/linux/bpf.h>
1010
#include <uapi/linux/seccomp.h>
1111
#include <uapi/linux/unistd.h>
12+
#include "syscall_nrs.h"
1213
#include "bpf_helpers.h"
1314

1415
#define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F
@@ -17,7 +18,11 @@ struct bpf_map_def SEC("maps") progs = {
1718
.type = BPF_MAP_TYPE_PROG_ARRAY,
1819
.key_size = sizeof(u32),
1920
.value_size = sizeof(u32),
21+
#ifdef __mips__
22+
.max_entries = 6000, /* MIPS n64 syscalls start at 5000 */
23+
#else
2024
.max_entries = 1024,
25+
#endif
2126
};
2227

2328
SEC("kprobe/__seccomp_filter")
@@ -37,7 +42,7 @@ int bpf_prog1(struct pt_regs *ctx)
3742
}
3843

3944
/* we jump here when syscall number == __NR_write */
40-
PROG(__NR_write)(struct pt_regs *ctx)
45+
PROG(SYS__NR_write)(struct pt_regs *ctx)
4146
{
4247
struct seccomp_data sd;
4348

@@ -50,7 +55,7 @@ PROG(__NR_write)(struct pt_regs *ctx)
5055
return 0;
5156
}
5257

53-
PROG(__NR_read)(struct pt_regs *ctx)
58+
PROG(SYS__NR_read)(struct pt_regs *ctx)
5459
{
5560
struct seccomp_data sd;
5661

@@ -63,7 +68,7 @@ PROG(__NR_read)(struct pt_regs *ctx)
6368
return 0;
6469
}
6570

66-
PROG(__NR_mmap)(struct pt_regs *ctx)
71+
PROG(SYS__NR_mmap)(struct pt_regs *ctx)
6772
{
6873
char fmt[] = "mmap\n";
6974
bpf_trace_printk(fmt, sizeof(fmt));

tools/net/bpf_jit_disasm.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,19 @@ static void put_log_buff(char *buff)
159159
free(buff);
160160
}
161161

162-
static unsigned int get_last_jit_image(char *haystack, size_t hlen,
163-
uint8_t *image, size_t ilen)
162+
static uint8_t *get_last_jit_image(char *haystack, size_t hlen,
163+
unsigned int *ilen)
164164
{
165165
char *ptr, *pptr, *tmp;
166166
off_t off = 0;
167167
int ret, flen, proglen, pass, ulen = 0;
168168
regmatch_t pmatch[1];
169169
unsigned long base;
170170
regex_t regex;
171+
uint8_t *image;
171172

172173
if (hlen == 0)
173-
return 0;
174+
return NULL;
174175

175176
ret = regcomp(&regex, "flen=[[:alnum:]]+ proglen=[[:digit:]]+ "
176177
"pass=[[:digit:]]+ image=[[:xdigit:]]+", REG_EXTENDED);
@@ -194,11 +195,22 @@ static unsigned int get_last_jit_image(char *haystack, size_t hlen,
194195
&flen, &proglen, &pass, &base);
195196
if (ret != 4) {
196197
regfree(&regex);
197-
return 0;
198+
return NULL;
199+
}
200+
if (proglen > 1000000) {
201+
printf("proglen of %d too big, stopping\n", proglen);
202+
return NULL;
198203
}
199204

205+
image = malloc(proglen);
206+
if (!image) {
207+
printf("Out of memory\n");
208+
return NULL;
209+
}
210+
memset(image, 0, proglen);
211+
200212
tmp = ptr = haystack + off;
201-
while ((ptr = strtok(tmp, "\n")) != NULL && ulen < ilen) {
213+
while ((ptr = strtok(tmp, "\n")) != NULL && ulen < proglen) {
202214
tmp = NULL;
203215
if (!strstr(ptr, "JIT code"))
204216
continue;
@@ -208,10 +220,12 @@ static unsigned int get_last_jit_image(char *haystack, size_t hlen,
208220
ptr = pptr;
209221
do {
210222
image[ulen++] = (uint8_t) strtoul(pptr, &pptr, 16);
211-
if (ptr == pptr || ulen >= ilen) {
223+
if (ptr == pptr) {
212224
ulen--;
213225
break;
214226
}
227+
if (ulen >= proglen)
228+
break;
215229
ptr = pptr;
216230
} while (1);
217231
}
@@ -222,7 +236,8 @@ static unsigned int get_last_jit_image(char *haystack, size_t hlen,
222236
printf("%lx + <x>:\n", base);
223237

224238
regfree(&regex);
225-
return ulen;
239+
*ilen = ulen;
240+
return image;
226241
}
227242

228243
static void usage(void)
@@ -237,12 +252,12 @@ static void usage(void)
237252
int main(int argc, char **argv)
238253
{
239254
unsigned int len, klen, opt, opcodes = 0;
240-
static uint8_t image[32768];
241255
char *kbuff, *file = NULL;
242256
char *ofile = NULL;
243257
int ofd;
244258
ssize_t nr;
245259
uint8_t *pos;
260+
uint8_t *image = NULL;
246261

247262
while ((opt = getopt(argc, argv, "of:O:")) != -1) {
248263
switch (opt) {
@@ -262,16 +277,15 @@ int main(int argc, char **argv)
262277
}
263278

264279
bfd_init();
265-
memset(image, 0, sizeof(image));
266280

267281
kbuff = get_log_buff(file, &klen);
268282
if (!kbuff) {
269283
fprintf(stderr, "Could not retrieve log buffer!\n");
270284
return -1;
271285
}
272286

273-
len = get_last_jit_image(kbuff, klen, image, sizeof(image));
274-
if (len <= 0) {
287+
image = get_last_jit_image(kbuff, klen, &len);
288+
if (!image) {
275289
fprintf(stderr, "No JIT image found!\n");
276290
goto done;
277291
}
@@ -301,5 +315,6 @@ int main(int argc, char **argv)
301315

302316
done:
303317
put_log_buff(kbuff);
318+
free(image);
304319
return 0;
305320
}

0 commit comments

Comments
 (0)