diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-04-30 17:39:13 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-04-30 17:44:09 -0700 |
commit | 7389e46cd013e0cd23af8a6531e9e104b5a31d09 (patch) | |
tree | 65a2567c46be9fa73f958cf1863f03925d335cda /pk | |
parent | 1a9aefdd006b660093283b039bfa8931319f8ae3 (diff) | |
download | pk-7389e46cd013e0cd23af8a6531e9e104b5a31d09.zip pk-7389e46cd013e0cd23af8a6531e9e104b5a31d09.tar.gz pk-7389e46cd013e0cd23af8a6531e9e104b5a31d09.tar.bz2 |
Move DRAM to high addresses
Diffstat (limited to 'pk')
-rw-r--r-- | pk/file.c | 12 | ||||
-rw-r--r-- | pk/mmap.c | 39 | ||||
-rw-r--r-- | pk/mmap.h | 4 | ||||
-rw-r--r-- | pk/pk.c | 2 | ||||
-rw-r--r-- | pk/pk.lds | 2 | ||||
-rw-r--r-- | pk/syscall.c | 22 |
6 files changed, 40 insertions, 41 deletions
@@ -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; } @@ -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; @@ -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 @@ -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. @@ -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) |