summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2013-07-04 14:20:24 +0200
committerRichard Braun <rbraun@sceen.net>2013-07-06 19:02:10 +0200
commit1c389aca56725700cf9e99805eb90feb0b94072b (patch)
tree22ca929244a33c5d2c699d1a8b16399b2f707de8
parentb6e66e8290ca33102714f34f66d2ed2062ba33f3 (diff)
page fault handling works !
-rw-r--r--arch/x86/machine/trap.c3
-rw-r--r--vm/vm_anon.c22
-rw-r--r--vm/vm_map.c27
-rw-r--r--vm/vm_object.c4
-rw-r--r--vm/vm_object.h2
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 <http://www.gnu.org/licenses/>.
*/
-#include <kern/kmem.h>
+#include <kern/error.h>
#include <kern/init.h>
+#include <kern/kmem.h>
#include <kern/list.h>
#include <kern/llsync.h>
#include <kern/macros.h>
@@ -27,6 +28,7 @@
#include <vm/vm_anon.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
+#include <vm/vm_phys.h>
/*
* 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
@@ -16,7 +16,6 @@
*/
#include <kern/rdxtree.h>
-#include <kern/rdxtree.h>
#include <kern/stddef.h>
#include <kern/stdint.h>
#include <vm/vm_object.h>
@@ -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