From 1c389aca56725700cf9e99805eb90feb0b94072b Mon Sep 17 00:00:00 2001 From: Richard Braun Date: Thu, 4 Jul 2013 14:20:24 +0200 Subject: page fault handling works ! --- arch/x86/machine/trap.c | 3 +++ vm/vm_anon.c | 22 +++++++++++++++------- vm/vm_map.c | 27 +++++++++++++++++++-------- vm/vm_object.c | 4 +++- vm/vm_object.h | 2 +- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/arch/x86/machine/trap.c b/arch/x86/machine/trap.c index 9ef26a27..c73084e7 100644 --- a/arch/x86/machine/trap.c +++ b/arch/x86/machine/trap.c @@ -194,6 +194,9 @@ trap_page_fault(struct trap_frame *frame) * can't cause another page fault while handling a page fault. */ addr = cpu_get_cr2(); + + cpu_intr_enable(); + access = (frame->error & TRAP_ERROR_PF_WRITE) ? VM_PROT_WRITE : VM_PROT_READ; diff --git a/vm/vm_anon.c b/vm/vm_anon.c index e923ff31..e6d1385f 100644 --- a/vm/vm_anon.c +++ b/vm/vm_anon.c @@ -15,8 +15,9 @@ * along with this program. If not, see . */ -#include +#include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include /* * Anonymous memory container. @@ -43,7 +45,7 @@ struct vm_anon { static void vm_anon_ref(struct vm_object *object); static void vm_anon_unref(struct vm_object *object); static int vm_anon_get(struct vm_object *object, uint64_t offset, - struct vm_page **pagep, int access_prot, int advice); + struct vm_page **pagep); static struct vm_object_pager vm_anon_pager = { .ref = vm_anon_ref, @@ -108,13 +110,19 @@ vm_anon_unref(struct vm_object *object) static int vm_anon_get(struct vm_object *object, uint64_t offset, - struct vm_page **pagep, int access_prot, int advice) + struct vm_page **pagep) { + struct vm_page *page; + + page = vm_phys_alloc(0); + + if (page == NULL) + return ERROR_NOMEM; + + /* TODO Insert page in object */ (void)object; (void)offset; - (void)pagep; - (void)access_prot; - (void)advice; - return -1; + *pagep = page; + return 0; } diff --git a/vm/vm_map.c b/vm/vm_map.c index 559beb2b..50e9c361 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -917,8 +917,10 @@ int vm_map_fault(struct vm_map *map, unsigned long addr, int access) { struct vm_map_entry *entry; + struct vm_object *object; struct vm_page *page; - int error; + uint64_t offset; + int error, prot; addr = vm_page_trunc(addr); @@ -938,18 +940,27 @@ vm_map_fault(struct vm_map *map, unsigned long addr, int access) /* Null mappings are reserved for the kernel and always wired */ assert(entry->object != NULL); - - page = vm_object_get(entry->object, entry->offset + (addr - entry->start)); + object = entry->object; + offset = entry->offset + (addr - entry->start); + page = vm_object_get(object, offset); if (page == NULL) { - /* TODO Get page from pager */ - error = ERROR_FAULT; - goto out; + /* TODO Get neighbor pages */ + error = object->pager->get(object, offset, &page); + + if (error) + goto out; } - /* TODO Map the page */ + prot = VM_MAP_PROT(entry->flags); + error = pmap_enter(map->pmap, addr, vm_page_to_pa(page), prot); + + /* TODO Properly handle errors */ + if (error) + panic("vm_map: unable to create physical mapping"); - error = ERROR_INVAL; + pmap_update(map->pmap, addr, addr + PAGE_SIZE); + error = 0; out: mutex_unlock(&map->lock); diff --git a/vm/vm_object.c b/vm/vm_object.c index d3cd9493..2fa2caae 100644 --- a/vm/vm_object.c +++ b/vm/vm_object.c @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -#include #include #include #include @@ -25,6 +24,9 @@ struct vm_page * vm_object_get(const struct vm_object *object, uint64_t offset) { + (void)object; + (void)offset; + /* TODO Bump radix tree key size to 64-bits */ return NULL; diff --git a/vm/vm_object.h b/vm/vm_object.h index b8b34aa9..578720ee 100644 --- a/vm/vm_object.h +++ b/vm/vm_object.h @@ -51,7 +51,7 @@ struct vm_object_pager { void (*ref)(struct vm_object *object); void (*unref)(struct vm_object *object); int (*get)(struct vm_object *object, uint64_t offset, - struct vm_page **pagep, int access_type, int advice); + struct vm_page **pagep); }; static inline void -- cgit v1.2.3