aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-04-30 17:39:13 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-04-30 17:44:09 -0700
commit7389e46cd013e0cd23af8a6531e9e104b5a31d09 (patch)
tree65a2567c46be9fa73f958cf1863f03925d335cda /pk
parent1a9aefdd006b660093283b039bfa8931319f8ae3 (diff)
downloadpk-7389e46cd013e0cd23af8a6531e9e104b5a31d09.zip
pk-7389e46cd013e0cd23af8a6531e9e104b5a31d09.tar.gz
pk-7389e46cd013e0cd23af8a6531e9e104b5a31d09.tar.bz2
Move DRAM to high addresses
Diffstat (limited to 'pk')
-rw-r--r--pk/file.c12
-rw-r--r--pk/mmap.c39
-rw-r--r--pk/mmap.h4
-rw-r--r--pk/pk.c2
-rw-r--r--pk/pk.lds2
-rw-r--r--pk/syscall.c22
6 files changed, 40 insertions, 41 deletions
diff --git a/pk/file.c b/pk/file.c
index 9176f1a..53087c3 100644
--- a/pk/file.c
+++ b/pk/file.c
@@ -91,7 +91,7 @@ file_t* file_openat(int dirfd, const char* fn, int flags, int mode)
return ERR_PTR(-ENOMEM);
size_t fn_size = strlen(fn)+1;
- long ret = frontend_syscall(SYS_openat, dirfd, (long)fn, fn_size, flags, mode, 0, 0);
+ long ret = frontend_syscall(SYS_openat, dirfd, va2pa(fn), fn_size, flags, mode, 0, 0);
if (ret >= 0)
{
f->kfd = ret;
@@ -120,31 +120,31 @@ 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, 0, 0, 0);
+ return frontend_syscall(SYS_read, f->kfd, va2pa(buf), size, 0, 0, 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, 0, 0, 0);
+ return frontend_syscall(SYS_pread, f->kfd, va2pa(buf), size, offset, 0, 0, 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, 0, 0, 0);
+ return frontend_syscall(SYS_write, f->kfd, va2pa(buf), size, 0, 0, 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, 0, 0, 0);
+ return frontend_syscall(SYS_pwrite, f->kfd, va2pa(buf), size, offset, 0, 0, 0);
}
int file_stat(file_t* f, struct stat* s)
{
struct frontend_stat buf;
- long ret = frontend_syscall(SYS_fstat, f->kfd, (uintptr_t)&buf, 0, 0, 0, 0, 0);
+ long ret = frontend_syscall(SYS_fstat, f->kfd, va2pa(&buf), 0, 0, 0, 0, 0);
copy_stat(s, &buf);
return ret;
}
diff --git a/pk/mmap.c b/pk/mmap.c
index 2f6a202..9f886ed 100644
--- a/pk/mmap.c
+++ b/pk/mmap.c
@@ -85,26 +85,21 @@ static size_t pt_idx(uintptr_t addr, int level)
return idx & ((1 << RISCV_PGLEVEL_BITS) - 1);
}
-static pte_t* __maybe_create_root_page_table()
+static pte_t* __walk_create(uintptr_t addr);
+
+static pte_t* __attribute__((noinline)) __continue_walk_create(uintptr_t addr, pte_t* pte)
{
- if (!root_page_table)
- root_page_table = (void*)__page_alloc();
- return root_page_table;
+ *pte = ptd_create(ppn(__page_alloc()));
+ return __walk_create(addr);
}
static pte_t* __walk_internal(uintptr_t addr, int create)
{
- pte_t* t = __maybe_create_root_page_table();
+ pte_t* t = root_page_table;
for (int i = (VA_BITS - RISCV_PGSHIFT) / RISCV_PGLEVEL_BITS - 1; i > 0; i--) {
size_t idx = pt_idx(addr, i);
- if (!(t[idx] & PTE_V)) {
- if (!create)
- return 0;
- uintptr_t page = __page_alloc();
- t[idx] = ptd_create(ppn(page));
- }
- else
- kassert(PTE_TABLE(t[idx]));
+ if (unlikely(!(t[idx] & PTE_V)))
+ return create ? __continue_walk_create(addr, &t[idx]) : 0;
t = (pte_t*)(pte_ppn(t[idx]) << RISCV_PGSHIFT);
}
return &t[pt_idx(addr, 0)];
@@ -176,7 +171,7 @@ int __valid_user_range(uintptr_t vaddr, size_t len)
{
if (vaddr + len < vaddr)
return 0;
- return vaddr >= first_free_paddr && vaddr + len <= current.mmap_max;
+ return vaddr + len <= current.mmap_max;
}
static int __handle_page_fault(uintptr_t vaddr, int prot)
@@ -190,7 +185,7 @@ static int __handle_page_fault(uintptr_t vaddr, int prot)
return -1;
else if (!(*pte & PTE_V))
{
- uintptr_t ppn = vpn;
+ uintptr_t ppn = vpn + (first_free_paddr / RISCV_PGSIZE);
vmr_t* v = (vmr_t*)*pte;
*pte = pte_create(ppn, prot_to_type(PROT_READ|PROT_WRITE, 0));
@@ -407,16 +402,16 @@ uintptr_t pk_vm_init()
{
size_t mem_pages = mem_size >> RISCV_PGSHIFT;
free_pages = MAX(8, mem_pages >> (RISCV_PGLEVEL_BITS-1));
- first_free_page = mem_size - free_pages * RISCV_PGSIZE;
+ first_free_page = first_free_paddr;
+ first_free_paddr += free_pages * RISCV_PGSIZE;
- __map_kernel_range(0, 0, first_free_paddr, PROT_READ|PROT_WRITE|PROT_EXEC);
- __map_kernel_range(first_free_page, first_free_page, free_pages * RISCV_PGSIZE, PROT_READ|PROT_WRITE);
+ root_page_table = (void*)__page_alloc();
+ __map_kernel_range(DRAM_BASE, DRAM_BASE, first_free_paddr - DRAM_BASE, PROT_READ|PROT_WRITE|PROT_EXEC);
- // keep user addresses positive
- current.mmap_max = MIN(first_free_page, (uintptr_t)INTPTR_MAX + 1);
- current.brk_max = current.mmap_max;
+ current.mmap_max = current.brk_max =
+ MIN(DRAM_BASE, mem_size - (first_free_paddr - DRAM_BASE));
- size_t stack_size = RISCV_PGSIZE * CLAMP(mem_size/(RISCV_PGSIZE*32), 1, 256);
+ size_t stack_size = RISCV_PGSIZE * 64;
size_t stack_bottom = __do_mmap(current.mmap_max - stack_size, stack_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
kassert(stack_bottom != (uintptr_t)-1);
current.stack_top = stack_bottom + stack_size;
diff --git a/pk/mmap.h b/pk/mmap.h
index e3c2035..3fc3186 100644
--- a/pk/mmap.h
+++ b/pk/mmap.h
@@ -5,6 +5,7 @@
#include "syscall.h"
#include "encoding.h"
#include "file.h"
+#include "mtrap.h"
#include <stddef.h>
#define PROT_NONE 0
@@ -31,4 +32,7 @@ uintptr_t do_mremap(uintptr_t addr, size_t old_size, size_t new_size, int flags)
uintptr_t do_mprotect(uintptr_t addr, size_t length, int prot);
uintptr_t do_brk(uintptr_t addr);
+#define va2pa(va) ({ uintptr_t __va = (uintptr_t)(va); \
+ __va >= DRAM_BASE ? __va : __va + first_free_paddr; })
+
#endif
diff --git a/pk/pk.c b/pk/pk.c
index 6878811..ab2e119 100644
--- a/pk/pk.c
+++ b/pk/pk.c
@@ -70,7 +70,7 @@ typedef union {
static size_t parse_args(arg_buf* args)
{
- long r = frontend_syscall(SYS_getmainvars, (uintptr_t)args, sizeof(*args), 0, 0, 0, 0, 0);
+ long r = frontend_syscall(SYS_getmainvars, va2pa(args), sizeof(*args), 0, 0, 0, 0, 0);
kassert(r == 0);
uint64_t* pk_argv = &args->buf[1];
// pk_argv[0] is the proxy kernel itself. skip it and any flags.
diff --git a/pk/pk.lds b/pk/pk.lds
index 0897e50..522e4a8 100644
--- a/pk/pk.lds
+++ b/pk/pk.lds
@@ -10,7 +10,7 @@ SECTIONS
/*--------------------------------------------------------------------*/
/* Begining of code and text segment */
- . = 0;
+ . = 0x80000000;
_ftext = .;
PROVIDE( eprol = . );
diff --git a/pk/syscall.c b/pk/syscall.c
index 1c9e234..9f2be88 100644
--- a/pk/syscall.c
+++ b/pk/syscall.c
@@ -111,8 +111,8 @@ int sys_renameat(int old_fd, const char *old_path, int new_fd, const char *new_p
if(old_kfd != -1 && new_kfd != -1) {
size_t old_size = strlen(old_path)+1;
size_t new_size = strlen(new_path)+1;
- return frontend_syscall(SYS_renameat, old_kfd, (uintptr_t)old_path, old_size,
- new_kfd, (uintptr_t)new_path, new_size, 0);
+ return frontend_syscall(SYS_renameat, old_kfd, va2pa(old_path), old_size,
+ new_kfd, va2pa(new_path), new_size, 0);
}
return -EBADF;
}
@@ -191,7 +191,7 @@ long sys_lstat(const char* name, void* st)
{
struct frontend_stat buf;
size_t name_size = strlen(name)+1;
- long ret = frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)&buf, 0, 0, 0, 0);
+ long ret = frontend_syscall(SYS_lstat, va2pa(name), name_size, va2pa(&buf), 0, 0, 0, 0);
copy_stat(st, &buf);
return ret;
}
@@ -202,7 +202,7 @@ long sys_fstatat(int dirfd, const char* name, void* st, int flags)
if (kfd != -1) {
struct frontend_stat buf;
size_t name_size = strlen(name)+1;
- long ret = frontend_syscall(SYS_fstatat, kfd, (uintptr_t)name, name_size, (uintptr_t)&buf, flags, 0, 0);
+ long ret = frontend_syscall(SYS_fstatat, kfd, va2pa(name), name_size, va2pa(&buf), flags, 0, 0);
copy_stat(st, &buf);
return ret;
}
@@ -219,7 +219,7 @@ long sys_faccessat(int dirfd, const char *name, int mode)
int kfd = at_kfd(dirfd);
if (kfd != -1) {
size_t name_size = strlen(name)+1;
- return frontend_syscall(SYS_faccessat, kfd, (uintptr_t)name, name_size, mode, 0, 0, 0);
+ return frontend_syscall(SYS_faccessat, kfd, va2pa(name), name_size, mode, 0, 0, 0);
}
return -EBADF;
}
@@ -236,8 +236,8 @@ long sys_linkat(int old_dirfd, const char* old_name, int new_dirfd, const char*
if (old_kfd != -1 && new_kfd != -1) {
size_t old_size = strlen(old_name)+1;
size_t new_size = strlen(new_name)+1;
- return frontend_syscall(SYS_linkat, old_kfd, (uintptr_t)old_name, old_size,
- new_kfd, (uintptr_t)new_name, new_size,
+ return frontend_syscall(SYS_linkat, old_kfd, va2pa(old_name), old_size,
+ new_kfd, va2pa(new_name), new_size,
flags);
}
return -EBADF;
@@ -253,7 +253,7 @@ long sys_unlinkat(int dirfd, const char* name, int flags)
int kfd = at_kfd(dirfd);
if (kfd != -1) {
size_t name_size = strlen(name)+1;
- return frontend_syscall(SYS_unlinkat, kfd, (uintptr_t)name, name_size, flags, 0, 0, 0);
+ return frontend_syscall(SYS_unlinkat, kfd, va2pa(name), name_size, flags, 0, 0, 0);
}
return -EBADF;
}
@@ -268,7 +268,7 @@ long sys_mkdirat(int dirfd, const char* name, int mode)
int kfd = at_kfd(dirfd);
if (kfd != -1) {
size_t name_size = strlen(name)+1;
- return frontend_syscall(SYS_mkdirat, kfd, (uintptr_t)name, name_size, mode, 0, 0, 0);
+ return frontend_syscall(SYS_mkdirat, kfd, va2pa(name), name_size, mode, 0, 0, 0);
}
return -EBADF;
}
@@ -281,7 +281,7 @@ long sys_mkdir(const char* name, int mode)
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, 0, 0);
+ return frontend_syscall(SYS_getcwd, va2pa(buf), size, 0, 0, 0, 0, 0);
}
size_t sys_brk(size_t pos)
@@ -384,7 +384,7 @@ ssize_t sys_writev(int fd, const long* iov, int cnt)
int sys_chdir(const char *path)
{
- return frontend_syscall(SYS_chdir, (uintptr_t)path, 0, 0, 0, 0, 0, 0);
+ return frontend_syscall(SYS_chdir, va2pa(path), 0, 0, 0, 0, 0, 0);
}
int sys_getdents(int fd, void* dirbuf, int count)