Skip to content

Commit

Permalink
Merge 390be10 into 0014f29
Browse files Browse the repository at this point in the history
  • Loading branch information
iomartin committed Apr 29, 2021
2 parents 0014f29 + 390be10 commit 6691dd4
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 6 deletions.
4 changes: 4 additions & 0 deletions test_framework/test_jit.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ def check_datafile(filename):
cmd = [VM]
if memfile:
cmd.extend(['-m', memfile.name])
if 'reload' in data:
cmd.extend(['-R'])
if 'unload' in data:
cmd.extend(['-u'])
cmd.extend(['-j', '-r', str(register_offset), '-'])

vm = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
Expand Down
4 changes: 4 additions & 0 deletions test_framework/test_vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def check_datafile(filename):
memfile.write(data['mem'])
memfile.flush()
cmd.extend(['-m', memfile.name])
if 'reload' in data:
cmd.extend(['-R'])
if 'unload' in data:
cmd.extend(['-u'])

cmd.append('-')

Expand Down
6 changes: 6 additions & 0 deletions tests/reload.data
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- reload
-- asm
mov r0, 0
exit
-- error
Failed to load code: code has already been loaded into this VM. Use ubpf_unload_code() if you need to reuse this VM
6 changes: 6 additions & 0 deletions tests/unload_reload.data
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- unload
-- asm
mov r0, 0
exit
-- result
0x0
11 changes: 11 additions & 0 deletions vm/inc/ubpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ int ubpf_register(struct ubpf_vm *vm, unsigned int idx, const char *name, void *
*/
int ubpf_load(struct ubpf_vm *vm, const void *code, uint32_t code_len, char **errmsg);

/*
* Unload code from a VM
*
* This must be done before calling ubpf_load or ubpf_load_elf, except for the
* first time those functions are called. It clears the VM instructions to
* allow for new code to be loaded.
*
* It does not unregister any external functions.
*/
void ubpf_unload_code(struct ubpf_vm *vm);

/*
* Load code from an ELF file
*
Expand Down
26 changes: 25 additions & 1 deletion vm/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ static void usage(const char *name)
fprintf(stderr, "If --jit is given then the JIT compiler will be used.\n");
fprintf(stderr, "\nOther options:\n");
fprintf(stderr, " -r, --register-offset NUM: Change the mapping from eBPF to x86 registers\n");
fprintf(stderr, " -u, --unload: unload the code and reload it (for testing only)\n");
fprintf(stderr, " -R, --reload: reload the code, without unloading it first (for testing only, this should fail)\n");
}

int main(int argc, char **argv)
Expand All @@ -49,14 +51,18 @@ int main(int argc, char **argv)
{ .name = "mem", .val = 'm', .has_arg=1 },
{ .name = "jit", .val = 'j' },
{ .name = "register-offset", .val = 'r', .has_arg=1 },
{ .name = "unload", .val = 'u' }, /* for unit test only */
{ .name = "reload", .val = 'R' }, /* for unit test only */
{ }
};

const char *mem_filename = NULL;
bool jit = false;
bool unload_reload = false;
bool reload = false;

int opt;
while ((opt = getopt_long(argc, argv, "hm:jr:", longopts, NULL)) != -1) {
while ((opt = getopt_long(argc, argv, "hm:jr:uR", longopts, NULL)) != -1) {
switch (opt) {
case 'm':
mem_filename = optarg;
Expand All @@ -70,12 +76,23 @@ int main(int argc, char **argv)
case 'h':
usage(argv[0]);
return 0;
case 'u':
unload_reload = true;
break;
case 'R':
reload = true;
break;
default:
usage(argv[0]);
return 1;
}
}

if (unload_reload && reload) {
fprintf(stderr, "-u and -R can not be used together\n");
return 1;
}

if (argc != optind + 1) {
usage(argv[0]);
return 1;
Expand Down Expand Up @@ -113,11 +130,18 @@ int main(int argc, char **argv)

char *errmsg;
int rv;
load:
if (elf) {
rv = ubpf_load_elf(vm, code, code_len, &errmsg);
} else {
rv = ubpf_load(vm, code, code_len, &errmsg);
}
if (unload_reload || reload) {
if (unload_reload)
ubpf_unload_code(vm);
unload_reload = reload = false;
goto load;
}

free(code);

Expand Down
22 changes: 17 additions & 5 deletions vm/ubpf_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ ubpf_create(void)
void
ubpf_destroy(struct ubpf_vm *vm)
{
if (vm->jitted) {
munmap(vm->jitted, vm->jitted_size);
}
free(vm->insts);
ubpf_unload_code(vm);
free(vm->ext_funcs);
free(vm->ext_func_names);
free(vm);
Expand Down Expand Up @@ -103,7 +100,7 @@ ubpf_load(struct ubpf_vm *vm, const void *code, uint32_t code_len, char **errmsg
*errmsg = NULL;

if (vm->insts) {
*errmsg = ubpf_error("code has already been loaded into this VM");
*errmsg = ubpf_error("code has already been loaded into this VM. Use ubpf_unload_code() if you need to reuse this VM");
return -1;
}

Expand All @@ -128,6 +125,21 @@ ubpf_load(struct ubpf_vm *vm, const void *code, uint32_t code_len, char **errmsg
return 0;
}

void
ubpf_unload_code(struct ubpf_vm *vm)
{
if (vm->jitted) {
munmap(vm->jitted, vm->jitted_size);
vm->jitted = NULL;
vm->jitted_size = 0;
}
if (vm->insts) {
free(vm->insts);
vm->insts = NULL;
vm->num_insts = 0;
}
}

static uint32_t
u32(uint64_t x)
{
Expand Down

0 comments on commit 6691dd4

Please sign in to comment.