summaryrefslogtreecommitdiff
path: root/vm/vm_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/vm_map.c')
-rw-r--r--vm/vm_map.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/vm/vm_map.c b/vm/vm_map.c
index f65ce5e5..559beb2b 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -917,16 +917,43 @@ int
vm_map_fault(struct vm_map *map, unsigned long addr, int access)
{
struct vm_map_entry *entry;
+ struct vm_page *page;
+ int error;
+
+ addr = vm_page_trunc(addr);
- (void)access;
+ mutex_lock(&map->lock);
entry = vm_map_fault_lookup(map, addr);
- if (entry == NULL)
- return ERROR_FAULT;
+ if (entry == NULL) {
+ error = ERROR_FAULT;
+ goto out;
+ }
+
+ if ((access & VM_MAP_PROT(entry->flags)) != access) {
+ error = ERROR_ACCES;
+ goto out;
+ }
- printk("vm_map: fault on entry %p\n", entry);
- return ERROR_AGAIN;
+ /* 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));
+
+ if (page == NULL) {
+ /* TODO Get page from pager */
+ error = ERROR_FAULT;
+ goto out;
+ }
+
+ /* TODO Map the page */
+
+ error = ERROR_INVAL;
+
+out:
+ mutex_unlock(&map->lock);
+ return error;
}
static void