diff options
author | Ian Moffett <ian@osmora.org> | 2024-05-05 23:09:30 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-05-05 23:09:53 -0400 |
commit | 7984343abd6e3f7f2be45ac42de4e1eac1030330 (patch) | |
tree | 012b6ccd8116e598b4bcb6deff7601a73a2eb7d6 /sys | |
parent | 0a7bc0f4c3234054608514c701d810b7c983d485 (diff) |
kernel: vm_fault: Refactor demand paging
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/vm/vm_fault.c | 44 |
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; } |