aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorColin Schmidt <colins@berkeley.edu>2014-05-22 18:56:56 -0700
committerColin Schmidt <colins@berkeley.edu>2014-05-22 18:56:56 -0700
commite50dc18f5df45ea358182ce7d986b77858219cd9 (patch)
tree67f91335fd545ca51de67df0d5dca8d976a30a3b /pk
parent894fe673b4f1326abd29512c8419759698d8ea2c (diff)
downloadpk-e50dc18f5df45ea358182ce7d986b77858219cd9.zip
pk-e50dc18f5df45ea358182ce7d986b77858219cd9.tar.gz
pk-e50dc18f5df45ea358182ce7d986b77858219cd9.tar.bz2
Add several syscalls, and move syscall header file from newlib
syscalls added (openat, access, accessat, faccessat, etc.)
Diffstat (limited to 'pk')
-rw-r--r--pk/file.c40
-rw-r--r--pk/file.h1
-rw-r--r--pk/frontend.c3
-rw-r--r--pk/frontend.h2
-rw-r--r--pk/init.c2
-rw-r--r--pk/syscall.c148
-rw-r--r--pk/syscall.h42
7 files changed, 218 insertions, 20 deletions
diff --git a/pk/file.c b/pk/file.c
index 5218061..b6847aa 100644
--- a/pk/file.c
+++ b/pk/file.c
@@ -7,9 +7,9 @@
#include "frontend.h"
#include "vm.h"
-#define MAX_FDS 32
+#define MAX_FDS 64
static atomic_t fds[MAX_FDS];
-#define MAX_FILES 32
+#define MAX_FILES 64
static file_t files[MAX_FILES] = {[0 ... MAX_FILES-1] = {-1,{0}}};
file_t *stdout, *stdin, *stderr;
@@ -26,7 +26,7 @@ void file_decref(file_t* f)
mb();
atomic_set(&f->refcnt, 0);
- frontend_syscall(SYS_close, kfd, 0, 0, 0);
+ frontend_syscall(SYS_close, kfd, 0, 0, 0, 0);
}
}
@@ -90,7 +90,27 @@ file_t* file_open(const char* fn, int flags, int mode)
return ERR_PTR(-ENOMEM);
size_t fn_size = strlen(fn)+1;
- long ret = frontend_syscall(SYS_open, (long)fn, fn_size, flags, mode);
+ long ret = frontend_syscall(SYS_open, (long)fn, fn_size, flags, mode, 0);
+ if (ret >= 0)
+ {
+ f->kfd = ret;
+ return f;
+ }
+ else
+ {
+ file_decref(f);
+ return ERR_PTR(ret);
+ }
+}
+
+file_t* file_openat(int dirfd, const char* fn, int flags, int mode)
+{
+ file_t* f = file_get_free();
+ if (f == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ size_t fn_size = strlen(fn)+1;
+ long ret = frontend_syscall(SYS_openat, dirfd, (long)fn, fn_size, flags, mode);
if (ret >= 0)
{
f->kfd = ret;
@@ -119,34 +139,34 @@ int fd_close(int fd)
ssize_t file_read(file_t* f, void* buf, size_t size)
{
populate_mapping(buf, size, PROT_WRITE);
- return frontend_syscall(SYS_read, f->kfd, (uintptr_t)buf, size, 0);
+ return frontend_syscall(SYS_read, f->kfd, (uintptr_t)buf, size, 0, 0);
}
ssize_t file_pread(file_t* f, void* buf, size_t size, off_t offset)
{
populate_mapping(buf, size, PROT_WRITE);
- return frontend_syscall(SYS_pread, f->kfd, (uintptr_t)buf, size, offset);
+ return frontend_syscall(SYS_pread, f->kfd, (uintptr_t)buf, size, offset, 0);
}
ssize_t file_write(file_t* f, const void* buf, size_t size)
{
populate_mapping(buf, size, PROT_READ);
- return frontend_syscall(SYS_write, f->kfd, (uintptr_t)buf, size, 0);
+ return frontend_syscall(SYS_write, f->kfd, (uintptr_t)buf, size, 0, 0);
}
ssize_t file_pwrite(file_t* f, const void* buf, size_t size, off_t offset)
{
populate_mapping(buf, size, PROT_READ);
- return frontend_syscall(SYS_pwrite, f->kfd, (uintptr_t)buf, size, offset);
+ return frontend_syscall(SYS_pwrite, f->kfd, (uintptr_t)buf, size, offset, 0);
}
int file_stat(file_t* f, struct stat* s)
{
populate_mapping(s, sizeof(*s), PROT_WRITE);
- return frontend_syscall(SYS_fstat, f->kfd, (uintptr_t)s, 0, 0);
+ return frontend_syscall(SYS_fstat, f->kfd, (uintptr_t)s, 0, 0, 0);
}
ssize_t file_lseek(file_t* f, size_t ptr, int dir)
{
- return frontend_syscall(SYS_lseek, f->kfd, ptr, dir, 0);
+ return frontend_syscall(SYS_lseek, f->kfd, ptr, dir, 0, 0);
}
diff --git a/pk/file.h b/pk/file.h
index 88338e6..c5b0f4b 100644
--- a/pk/file.h
+++ b/pk/file.h
@@ -21,6 +21,7 @@ void file_decref(file_t*);
void file_incref(file_t*);
int file_dup(file_t*);
+file_t* file_openat(int dirfd, const char* fn, int flags, int mode);
ssize_t file_pwrite(file_t* f, const void* buf, size_t n, off_t off);
ssize_t file_pread(file_t* f, void* buf, size_t n, off_t off);
ssize_t file_write(file_t* f, const void* buf, size_t n);
diff --git a/pk/frontend.c b/pk/frontend.c
index 77d71a6..4c6051e 100644
--- a/pk/frontend.c
+++ b/pk/frontend.c
@@ -5,7 +5,7 @@
#include "frontend.h"
#include <stdint.h>
-long frontend_syscall(long n, long a0, long a1, long a2, long a3)
+long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4)
{
static volatile uint64_t magic_mem[8];
@@ -17,6 +17,7 @@ long frontend_syscall(long n, long a0, long a1, long a2, long a3)
magic_mem[2] = a1;
magic_mem[3] = a2;
magic_mem[4] = a3;
+ magic_mem[5] = a4;
mb();
diff --git a/pk/frontend.h b/pk/frontend.h
index 9610234..edbf22a 100644
--- a/pk/frontend.h
+++ b/pk/frontend.h
@@ -3,6 +3,6 @@
#ifndef _RISCV_FRONTEND_H
#define _RISCV_FRONTEND_H
-long frontend_syscall(long n, long a0, long a1, long a2, long a3);
+long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4);
#endif
diff --git a/pk/init.c b/pk/init.c
index d6974f7..46e3228 100644
--- a/pk/init.c
+++ b/pk/init.c
@@ -54,7 +54,7 @@ static void user_init()
size_t stack_top = current.stack_top;
struct args* args = (struct args*)(stack_top - argc_argv_size);
populate_mapping(args, argc_argv_size, PROT_WRITE);
- long r = frontend_syscall(SYS_getmainvars, (long)args, argc_argv_size, 0, 0);
+ long r = frontend_syscall(SYS_getmainvars, (long)args, argc_argv_size, 0, 0, 0);
kassert(r == 0);
// argv[0] is the proxy kernel itself. skip it and any flags.
diff --git a/pk/syscall.c b/pk/syscall.c
index 6d58be0..e25b883 100644
--- a/pk/syscall.c
+++ b/pk/syscall.c
@@ -7,6 +7,7 @@
#include "vm.h"
#include <string.h>
#include <errno.h>
+//#include <fcntl.h>
typedef long (*syscall_t)(long, long, long, long, long, long, long);
@@ -26,7 +27,7 @@ void sys_exit(int code)
if (current.t0)
printk("%ld cycles\n", rdcycle() - current.t0);
- frontend_syscall(SYS_exit, code, 0, 0, 0);
+ frontend_syscall(SYS_exit, code, 0, 0, 0, 0);
while (1);
}
@@ -44,6 +45,20 @@ ssize_t sys_read(int fd, char* buf, size_t n)
return r;
}
+ssize_t sys_pread(int fd, char* buf, size_t n, off_t offset)
+{
+ ssize_t r = -EBADF;
+ file_t* f = file_get(fd);
+
+ if (f)
+ {
+ r = file_pread(f, buf, n, offset);
+ file_decref(f);
+ }
+
+ return r;
+}
+
ssize_t sys_write(int fd, const char* buf, size_t n)
{
ssize_t r = -EBADF;
@@ -60,6 +75,7 @@ ssize_t sys_write(int fd, const char* buf, size_t n)
int sys_open(const char* name, int flags, int mode)
{
+ printk("OPEN(%s)\n",name);
file_t* file = file_open(name, flags, mode);
if (IS_ERR_VALUE(file))
return PTR_ERR(file);
@@ -71,8 +87,30 @@ int sys_open(const char* name, int flags, int mode)
return fd;
}
+int sys_openat(int dirfd, const char* name, int flags, int mode)
+{
+ if(name[0] == '/'){
+ return sys_open(name, flags, mode);
+ }
+ file_t* dir = file_get(dirfd);
+ if(dir)
+ {
+ file_t* file = file_openat(dir->kfd, name, flags, mode);
+ if (IS_ERR_VALUE(file))
+ return PTR_ERR(file);
+
+ int fd = file_dup(file);
+ if (fd < 0)
+ return -ENOMEM;
+
+ return fd;
+ }
+ return -EBADF;
+}
+
int sys_close(int fd)
{
+ //printk("CLOSE(%ld)\n",fd);
int ret = fd_close(fd);
if (ret < 0)
return -EBADF;
@@ -81,6 +119,7 @@ int sys_close(int fd)
int sys_fstat(int fd, void* st)
{
+ printk("FSTAT(%ld)\n",fd);
int r = -EBADF;
file_t* f = file_get(fd);
@@ -93,6 +132,34 @@ int sys_fstat(int fd, void* st)
return r;
}
+int sys_fcntl(int fd, int cmd, int arg)
+{
+ int r = -EBADF;
+ file_t* f = file_get(fd);
+
+ if (f)
+ {
+ r = frontend_syscall(SYS_fcntl, f->kfd, cmd, arg, 0, 0);
+ file_decref(f);
+ }
+
+ return r;
+}
+
+int sys_dup(int fd)
+{
+ int r = -EBADF;
+ file_t* f = file_get(fd);
+
+ if (f)
+ {
+ r = file_dup(f);
+ file_decref(f);
+ }
+
+ return r;
+}
+
ssize_t sys_lseek(int fd, size_t ptr, int dir)
{
ssize_t r = -EBADF;
@@ -111,14 +178,46 @@ long sys_stat(const char* name, void* st)
{
size_t name_size = strlen(name)+1;
populate_mapping(st, sizeof(struct stat), PROT_WRITE);
- return frontend_syscall(SYS_stat, (uintptr_t)name, name_size, (uintptr_t)st, 0);
+ return frontend_syscall(SYS_stat, (uintptr_t)name, name_size, (uintptr_t)st, 0, 0);
}
long sys_lstat(const char* name, void* st)
{
size_t name_size = strlen(name)+1;
populate_mapping(st, sizeof(struct stat), PROT_WRITE);
- return frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)st, 0);
+ return frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)st, 0, 0);
+}
+long sys_fstatat(int dirfd, const char* name, void* st, int flags)
+{
+ if(name[0] == '/'){
+ return sys_stat(name, st);
+ }
+ file_t* dir = file_get(dirfd);
+ if(dir)
+ {
+ size_t name_size = strlen(name)+1;
+ populate_mapping(st, sizeof(struct stat), PROT_WRITE);
+ return frontend_syscall(SYS_fstatat, dir->kfd, (uintptr_t)name, name_size, (uintptr_t)st, flags);
+ }
+ return -EBADF;
+}
+
+int sys_access(const char *name, int mode){
+ size_t name_size = strlen(name)+1;
+ return frontend_syscall(SYS_access, (uintptr_t)name, name_size, mode, 0, 0);
+}
+
+int sys_faccessat(int dirfd, const char *name, int mode, int flags){
+ if(name[0] == '/'){
+ return sys_access(name, mode);
+ }
+ file_t* dir = file_get(dirfd);
+ if(dir)
+ {
+ size_t name_size = strlen(name)+1;
+ return frontend_syscall(SYS_access, dir->kfd, (uintptr_t)name, name_size, mode, flags);
+ }
+ return -EBADF;
}
long sys_link(const char* old_name, const char* new_name)
@@ -126,13 +225,25 @@ long sys_link(const char* old_name, const char* new_name)
size_t old_size = strlen(old_name)+1;
size_t new_size = strlen(new_name)+1;
return frontend_syscall(SYS_link, (uintptr_t)old_name, old_size,
- (uintptr_t)new_name, new_size);
+ (uintptr_t)new_name, new_size, 0);
}
long sys_unlink(const char* name, size_t len)
{
size_t name_size = strlen(name)+1;
- return frontend_syscall(SYS_unlink, (uintptr_t)name, name_size, 0, 0);
+ return frontend_syscall(SYS_unlink, (uintptr_t)name, name_size, 0, 0, 0);
+}
+
+long sys_mkdir(const char* name, int mode)
+{
+ size_t name_size = strlen(name)+1;
+ return frontend_syscall(SYS_mkdir, (uintptr_t)name, name_size, mode, 0, 0);
+}
+
+long sys_getcwd(const char* buf, size_t size)
+{
+ populate_mapping(buf, size, PROT_WRITE);
+ return frontend_syscall(SYS_getcwd, (uintptr_t)buf, size, 0, 0, 0);
}
size_t sys_brk(size_t pos)
@@ -152,6 +263,11 @@ int sys_uname(void* buf)
return 0;
}
+pid_t sys_getpid()
+{
+ return 0;
+}
+
int sys_getuid()
{
return 0;
@@ -159,7 +275,10 @@ int sys_getuid()
uintptr_t sys_mmap(uintptr_t addr, size_t length, int prot, int flags, int fd, off_t offset)
{
- return do_mmap(addr, length, prot, flags, fd, offset);
+ printk("MMAP(ad:%ld,len:%ld,prot:%ld,flags:%ld,fd:%ld,off:%ld\n",addr,length,prot,flags,fd,offset);
+ uintptr_t ret = do_mmap(addr, length, prot, flags, fd, offset);
+ //printk("MMAP DONE\n");
+ return ret;
}
int sys_munmap(uintptr_t addr, size_t length)
@@ -235,23 +354,35 @@ ssize_t sys_writev(int fd, const void* iov, int cnt)
return ret;
}
+
+int sys_getdents(int fd, void* dirbuf, int count)
+{
+ return 0; //stub
+}
+
long syscall(long a0, long a1, long a2, long a3, long a4, long a5, long n)
{
const static void* syscall_table[] = {
[SYS_exit] = sys_exit,
[SYS_exit_group] = sys_exit,
[SYS_read] = sys_read,
+ [SYS_pread] = sys_pread,
[SYS_write] = sys_write,
[SYS_open] = sys_open,
+ [SYS_openat] = sys_openat,
[SYS_close] = sys_close,
[SYS_fstat] = sys_fstat,
[SYS_lseek] = sys_lseek,
[SYS_stat] = sys_stat,
[SYS_lstat] = sys_lstat,
+ [SYS_fstatat] = sys_fstatat,
[SYS_link] = sys_link,
[SYS_unlink] = sys_unlink,
+ [SYS_mkdir] = sys_mkdir,
+ [SYS_getcwd] = sys_getcwd,
[SYS_brk] = sys_brk,
[SYS_uname] = sys_uname,
+ [SYS_getpid] = sys_getpid,
[SYS_getuid] = sys_getuid,
[SYS_geteuid] = sys_getuid,
[SYS_getgid] = sys_getuid,
@@ -264,6 +395,11 @@ long syscall(long a0, long a1, long a2, long a3, long a4, long a5, long n)
[SYS_gettimeofday] = sys_gettimeofday,
[SYS_times] = sys_times,
[SYS_writev] = sys_writev,
+ [SYS_access] = sys_access,
+ [SYS_faccessat] = sys_faccessat,
+ [SYS_fcntl] = sys_fcntl,
+ [SYS_getdents] = sys_getdents,
+ [SYS_dup] = sys_dup,
};
if(n >= ARRAY_SIZE(syscall_table) || !syscall_table[n])
diff --git a/pk/syscall.h b/pk/syscall.h
index fcb3423..e3a88ce 100644
--- a/pk/syscall.h
+++ b/pk/syscall.h
@@ -3,7 +3,47 @@
#ifndef _PK_SYSCALL_H
#define _PK_SYSCALL_H
-#include <machine/syscall.h>
+#define SYS_exit 93
+#define SYS_exit_group 94
+#define SYS_getpid 172
+#define SYS_kill 129
+#define SYS_read 63
+#define SYS_write 64
+#define SYS_open 1024
+#define SYS_openat 56
+#define SYS_close 57
+#define SYS_lseek 62
+#define SYS_brk 214
+#define SYS_link 1025
+#define SYS_unlink 1026
+#define SYS_mkdir 1030
+#define SYS_chdir 49
+#define SYS_getcwd 17
+#define SYS_stat 1038
+#define SYS_fstat 80
+#define SYS_lstat 1039
+#define SYS_fstatat 79
+#define SYS_access 1033
+#define SYS_faccessat 48
+#define SYS_pread 67
+#define SYS_pwrite 68
+#define SYS_uname 160
+#define SYS_getuid 174
+#define SYS_geteuid 175
+#define SYS_getgid 176
+#define SYS_getegid 177
+#define SYS_mmap 222
+#define SYS_munmap 215
+#define SYS_mremap 216
+#define SYS_time 1062
+#define SYS_getmainvars 2011
+#define SYS_rt_sigaction 134
+#define SYS_writev 66
+#define SYS_gettimeofday 169
+#define SYS_times 153
+#define SYS_fcntl 25
+#define SYS_getdents 61
+#define SYS_dup 23
#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-4096)
#define ERR_PTR(x) ((void*)(long)(x))