aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/vm/vm_fault.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index ec733e8..d1a3e29 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -74,18 +74,36 @@ vm_find_mapping(vaddr_t addr)
return NULL;
}
+static int
+vm_demand_page(struct vm_mapping *mapping, vaddr_t va, vm_prot_t access_type)
+{
+ struct proc *td;
+ paddr_t pa_base;
+
+ int s;
+ size_t granule = vm_get_page_size();
+
+ /* Allocate physical memory if needed */
+ if (mapping->physmem_base == 0) {
+ pa_base = vm_alloc_pageframe(1);
+ mapping->physmem_base = pa_base;
+ } else {
+ pa_base = mapping->physmem_base;
+ }
+
+ td = this_td();
+ s = vm_map_create(td->addrsp, va, pa_base, access_type, granule);
+ return s;
+}
+
int
vm_fault(vaddr_t va, vm_prot_t access_type)
{
- struct proc *td = this_td();
struct vm_mapping *mapping;
struct vm_object *vmobj;
size_t granule = vm_get_page_size();
- vaddr_t va_base = va &= ~(granule - 1);
-
- int s;
- paddr_t pa_base;
+ vaddr_t va_base = va & ~(granule - 1);
mapping = vm_find_mapping(va_base);
if (mapping == NULL)
@@ -94,21 +112,15 @@ vm_fault(vaddr_t va, vm_prot_t access_type)
if ((vmobj = mapping->vmobj) == NULL)
/* Virtual memory object non-existent */
return -1;
- if (!vmobj->demand)
- /* Demand paging not enabled for this object */
- return -1;
if ((access_type & ~mapping->prot) != 0)
/* Invalid access type */
return -1;
- /* Allocate physical memory if needed */
- if (mapping->physmem_base == 0) {
- pa_base = vm_alloc_pageframe(1);
- mapping->physmem_base = pa_base;
- } else {
- pa_base = mapping->physmem_base;
+ /* Can we perform demand paging? */
+ if (vmobj->demand) {
+ if (vm_demand_page(mapping, va_base, access_type) != 0)
+ return -1;
}
- s = vm_map_create(td->addrsp, va_base, pa_base, access_type, granule);
- return s;
+ return 0;
}