1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#include "api/error.h"
#include "api/syscall.h"
#include "hal/memory.h"
#include "lib/printf.h"
#include "jove.h"
#include "syscall.h"
static int
s_syscall_region_alloc(jove_owned_obj_t *region_obj,
jove_owned_obj_t *objdir_obj,
lockstack_t *lockstack,
size_t bytes_left,
void *payload_data)
{
size_t bytes_needed = sizeof(struct syscall_region_alloc);
CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload");
struct syscall_region_alloc *payload = payload_data;
bytes_needed += payload->dest_pathlen * sizeof(objpath_part_t);
CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for subject path");
jove_perm_obj_t subject = link_try_traverse_objdir(
objdir_obj, lockstack, payload->dest_pathlen, payload->dest_path);
CHECK_OBJEXISTS(subject.obj, "Destination path is bad.");
CHECK_OBJPERM(subject, SYSCALL_PERM_REGION_ALLOC_TGT, "Destination path does not have correct permissions.");
CHECK_OBJTYPE(subject.obj, JOVE_OBJ_NONE, "Destination object is not JOVE_OBJ_NONE");
int sysret = 0;
if(payload->alloc_pages == 1) {
sysret = region_alloc(region_obj, subject.obj);
}else{
sysret = region_alloc_contig(region_obj, subject.obj, payload->alloc_pages);
}
if(sysret < 0) {
klogf("Region alloc failed with reason: %s\n", errstr(-sysret));
}
return sysret;
}
int
_syscall_handle_region(syscall_context_t *ctx)
{
switch(ctx->header->callid) {
case SYSCALL_REGION_ADDRESS:
if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS)
return region_base(ctx->target.obj);
return -EPERM;
case SYSCALL_REGION_TOTAL_PAGES:
if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS)
return region_pages(ctx->target.obj);
return -EPERM;
case SYSCALL_REGION_FREE_PAGES:
if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS)
return region_freepages(ctx->target.obj);
return -EPERM;
case SYSCALL_REGION_ALLOC:
if(ctx->target.permissions & SYSCALL_PERM_REGION_ALLOC)
return s_syscall_region_alloc(ctx->target.obj, ctx->objdir, &ctx->lockstack, ctx->bytes_left, ctx->payload);
return -EPERM;
default:
return -EBADCALL;
}
}
|