From 96e01a27bffd323883c58cf6c2f0f93275a0234e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 20 Dec 2005 13:29:11 +0000 Subject: [PATCH] * Merged vm_virtual_map with vm_address_space - there was no reason to have them apart (this even saves a pointer from vm_virtual_map to its address space) * aspace -> address_space * vm_create_address_space() did not check if creating the semaphore succeeded * Removed team::kaspace - was not really needed (introduced a new vm_kernel_address_space() function that doesn't grab a reference to the address space) * Removed vm_address_space::name - it was just a copy of the team name, anyway, and there is always only one address space per team * Removed aspace_id - the address space is now using the team_id * Some cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15609 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/thread_types.h | 3 +- headers/private/kernel/vm.h | 43 +- headers/private/kernel/vm_types.h | 30 +- src/system/kernel/arch/x86/arch_thread.c | 22 +- .../kernel/arch/x86/arch_vm_translation_map.c | 4 +- src/system/kernel/cache/block_allocator.cpp | 11 +- src/system/kernel/elf.c | 14 +- src/system/kernel/team.c | 32 +- src/system/kernel/thread.c | 4 +- src/system/kernel/vm/vm.cpp | 628 +++++++++--------- src/system/kernel/vm/vm_address_space.c | 178 +++-- src/system/kernel/vm/vm_daemons.c | 20 +- src/system/kernel/vm/vm_page.c | 4 +- src/system/kernel/vm/vm_tests.c | 74 +-- 14 files changed, 528 insertions(+), 539 deletions(-) diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index a34afbfce4..3b62d84474 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -111,8 +111,7 @@ struct team { bigtime_t kernel_time; bigtime_t user_time; } dead_children; - struct vm_address_space *aspace; - struct vm_address_space *kaspace; + struct vm_address_space *address_space; struct thread *main_thread; struct thread *thread_list; struct team_loading_info *loading_info; diff --git a/headers/private/kernel/vm.h b/headers/private/kernel/vm.h index 07144abea6..aae018dcd0 100644 --- a/headers/private/kernel/vm.h +++ b/headers/private/kernel/vm.h @@ -25,22 +25,23 @@ status_t vm_init(kernel_args *args); status_t vm_init_post_sem(struct kernel_args *args); status_t vm_init_post_thread(struct kernel_args *args); status_t vm_init_post_modules(struct kernel_args *args); -status_t vm_aspace_init(void); -status_t vm_aspace_init_post_sem(void); +status_t vm_address_space_init(void); +status_t vm_address_space_init_post_sem(void); void vm_free_kernel_args(kernel_args *args); void vm_free_unused_boot_loader_range(addr_t start, addr_t end); -void vm_delete_aspace(vm_address_space *aspace); -status_t vm_create_aspace(const char *name, team_id id, addr_t base, addr_t size, +void vm_delete_address_space(vm_address_space *aspace); +status_t vm_create_address_space(team_id id, addr_t base, addr_t size, bool kernel, vm_address_space **_aspace); status_t vm_delete_areas(struct vm_address_space *aspace); -vm_address_space *vm_get_kernel_aspace(void); -aspace_id vm_get_kernel_aspace_id(void); -vm_address_space *vm_get_current_user_aspace(void); -aspace_id vm_get_current_user_aspace_id(void); -vm_address_space *vm_get_aspace_by_id(aspace_id aid); -void vm_put_aspace(vm_address_space *aspace); -#define vm_aspace_swap(aspace) arch_vm_aspace_swap(aspace) +vm_address_space *vm_get_kernel_address_space(void); +vm_address_space *vm_kernel_address_space(void); +team_id vm_kernel_address_space_id(void); +vm_address_space *vm_get_current_user_address_space(void); +team_id vm_current_user_address_space_id(void); +vm_address_space *vm_get_address_space_by_id(team_id aid); +void vm_put_address_space(vm_address_space *aspace); +#define vm_swap_address_space(aspace) arch_vm_aspace_swap(aspace) // private kernel only extension (should be moved somewhere else): struct team; @@ -48,29 +49,29 @@ area_id create_area_etc(struct team *team, const char *name, void **address, uint32 addressSpec, uint32 size, uint32 lock, uint32 protection); status_t delete_area_etc(struct team *team, area_id area); -status_t vm_unreserve_address_range(aspace_id aid, void *address, addr_t size); -status_t vm_reserve_address_range(aspace_id aid, void **_address, +status_t vm_unreserve_address_range(team_id aid, void *address, addr_t size); +status_t vm_reserve_address_range(team_id aid, void **_address, uint32 addressSpec, addr_t size, uint32 flags); -area_id vm_create_anonymous_area(aspace_id aid, const char *name, void **address, +area_id vm_create_anonymous_area(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 wiring, uint32 protection); -area_id vm_map_physical_memory(aspace_id aid, const char *name, void **address, +area_id vm_map_physical_memory(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 protection, addr_t phys_addr); -area_id vm_map_file(aspace_id aid, const char *name, void **address, +area_id vm_map_file(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 protection, uint32 mapping, const char *path, off_t offset); -area_id vm_create_null_area(aspace_id aid, const char *name, void **address, +area_id vm_create_null_area(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size); -area_id vm_copy_area(aspace_id addressSpaceID, const char *name, void **_address, +area_id vm_copy_area(team_id addressSpaceID, const char *name, void **_address, uint32 addressSpec, uint32 protection, area_id sourceID); -area_id vm_clone_area(aspace_id aid, const char *name, void **address, +area_id vm_clone_area(team_id aid, const char *name, void **address, uint32 addressSpec, uint32 protection, uint32 mapping, area_id sourceArea); -status_t vm_delete_area(aspace_id aid, area_id id); +status_t vm_delete_area(team_id aid, area_id id); status_t vm_create_vnode_cache(void *vnode, vm_cache_ref **_cacheRef); status_t vm_set_area_memory_type(area_id id, addr_t physicalBase, uint32 type); -status_t vm_get_page_mapping(aspace_id aid, addr_t vaddr, addr_t *paddr); +status_t vm_get_page_mapping(team_id aid, addr_t vaddr, addr_t *paddr); status_t vm_get_physical_page(addr_t paddr, addr_t *vaddr, int flags); status_t vm_put_physical_page(addr_t vaddr); diff --git a/headers/private/kernel/vm_types.h b/headers/private/kernel/vm_types.h index f0bdae1367..084802a529 100644 --- a/headers/private/kernel/vm_types.h +++ b/headers/private/kernel/vm_types.h @@ -15,8 +15,6 @@ #include -typedef int32 aspace_id; - // vm page typedef struct vm_page { struct vm_page *queue_prev; @@ -90,25 +88,13 @@ typedef struct vm_area { struct vm_cache_ref *cache_ref; off_t cache_offset; - struct vm_address_space *aspace; - struct vm_area *aspace_next; - struct vm_virtual_map *map; + struct vm_address_space *address_space; + struct vm_area *address_space_next; struct vm_area *cache_next; struct vm_area *cache_prev; struct vm_area *hash_next; } vm_area; -// virtual map (1 per address space) -typedef struct vm_virtual_map { - vm_area *areas; - vm_area *area_hint; - int change_count; - sem_id sem; - struct vm_address_space *aspace; - addr_t base; - addr_t size; -} vm_virtual_map; - enum { VM_ASPACE_STATE_NORMAL = 0, VM_ASPACE_STATE_DELETION @@ -116,13 +102,17 @@ enum { // address space typedef struct vm_address_space { - vm_virtual_map virtual_map; + vm_area *areas; + vm_area *area_hint; + sem_id sem; + addr_t base; + addr_t size; + int32 change_count; vm_translation_map translation_map; - char *name; - aspace_id id; + team_id id; int32 ref_count; int32 fault_count; - int state; + int32 state; addr_t scan_va; addr_t working_set_size; addr_t max_working_set; diff --git a/src/system/kernel/arch/x86/arch_thread.c b/src/system/kernel/arch/x86/arch_thread.c index da1e7946e9..cfb7a7522a 100644 --- a/src/system/kernel/arch/x86/arch_thread.c +++ b/src/system/kernel/arch/x86/arch_thread.c @@ -115,23 +115,23 @@ i386_get_user_iframe(void) inline void * x86_next_page_directory(struct thread *from, struct thread *to) { - if (from->team->aspace != NULL && to->team->aspace != NULL) { - // they are both uspace threads + if (from->team->address_space != NULL && to->team->address_space != NULL) { + // they are both user space threads if (from->team == to->team) { // dont change the pgdir, same address space return NULL; } // switching to a new address space - return i386_translation_map_get_pgdir(&to->team->aspace->translation_map); - } else if (from->team->aspace == NULL && to->team->aspace == NULL) { - // they must both be kspace threads + return i386_translation_map_get_pgdir(&to->team->address_space->translation_map); + } else if (from->team->address_space == NULL && to->team->address_space == NULL) { + // they must both be kernel space threads return NULL; - } else if (to->team->aspace == NULL) { - // the one we're switching to is kspace - return i386_translation_map_get_pgdir(&to->team->kaspace->translation_map); + } else if (to->team->address_space == NULL) { + // the one we're switching to is kernel space + return i386_translation_map_get_pgdir(&vm_kernel_address_space()->translation_map); } - return i386_translation_map_get_pgdir(&to->team->aspace->translation_map); + return i386_translation_map_get_pgdir(&to->team->address_space->translation_map); } @@ -257,7 +257,7 @@ arch_thread_context_switch(struct thread *from, struct thread *to) dprintf("arch_thread_context_switch: cpu %d 0x%x -> 0x%x, aspace 0x%x -> 0x%x, old stack = 0x%x:0x%x, stack = 0x%x:0x%x\n", smp_get_current_cpu(), t_from->id, t_to->id, - t_from->team->aspace, t_to->team->aspace, + t_from->team->address_space, t_to->team->address_space, t_from->arch_info.current_stack.ss, t_from->arch_info.current_stack.esp, t_to->arch_info.current_stack.ss, t_to->arch_info.current_stack.esp); #endif @@ -279,7 +279,7 @@ arch_thread_context_switch(struct thread *from, struct thread *to) // reinit debugging; necessary, if the thread was preempted after // initializing debugging before returning to userland - if (to->team->aspace != NULL) + if (to->team->address_space != NULL) i386_reinit_user_debug_after_context_switch(to); i386_fsave_swap(from->arch_info.fpu_state, to->arch_info.fpu_state); diff --git a/src/system/kernel/arch/x86/arch_vm_translation_map.c b/src/system/kernel/arch/x86/arch_vm_translation_map.c index 94df0b1a6d..5fc4d05a55 100644 --- a/src/system/kernel/arch/x86/arch_vm_translation_map.c +++ b/src/system/kernel/arch/x86/arch_vm_translation_map.c @@ -833,7 +833,7 @@ arch_vm_translation_map_init_map(vm_translation_map *map, bool kernel) recursive_lock_destroy(&map->lock); return B_NO_MEMORY; } - vm_get_page_mapping(vm_get_kernel_aspace_id(), + vm_get_page_mapping(vm_kernel_address_space_id(), (addr_t)map->arch_data->pgdir_virt, (addr_t *)&map->arch_data->pgdir_phys); } else { // kernel @@ -995,7 +995,7 @@ arch_vm_translation_map_init_post_area(kernel_args *args) TRACE(("vm_translation_map_init_post_area: creating iospace\n")); temp = (void *)IOSPACE_BASE; - vm_create_null_area(vm_get_kernel_aspace_id(), "iospace", &temp, + vm_create_null_area(vm_kernel_address_space_id(), "iospace", &temp, B_EXACT_ADDRESS, IOSPACE_SIZE); TRACE(("vm_translation_map_init_post_area: done\n")); diff --git a/src/system/kernel/cache/block_allocator.cpp b/src/system/kernel/cache/block_allocator.cpp index 3cba6209d1..cbef9254a9 100644 --- a/src/system/kernel/cache/block_allocator.cpp +++ b/src/system/kernel/cache/block_allocator.cpp @@ -92,8 +92,8 @@ BlockAddressPool::BlockAddressPool() fBase = 0xa0000000; // directly after the I/O space area - fArea = vm_create_null_area(vm_get_kernel_aspace_id(), "block cache", (void **)&fBase, - B_BASE_ADDRESS, kBlockAddressSize); + fArea = vm_create_null_area(vm_kernel_address_space_id(), "block cache", + (void **)&fBase, B_BASE_ADDRESS, kBlockAddressSize); fFirstFree = fBase; fNextFree = -1; @@ -216,15 +216,13 @@ block_range::Delete(block_cache *cache, block_range *range) // unmap the memory - vm_address_space *addressSpace = vm_get_kernel_aspace(); + vm_address_space *addressSpace = vm_kernel_address_space(); vm_translation_map *map = &addressSpace->translation_map; map->ops->lock(map); map->ops->unmap(map, range->base, range->base + kBlockRangeSize - 1); map->ops->unlock(map); - vm_put_aspace(addressSpace); - sBlockAddressPool.Put(range->base); // free pages @@ -355,7 +353,7 @@ block_range::Allocate(block_cache *cache, block_chunk **_chunk) // map the memory - vm_address_space *addressSpace = vm_get_kernel_aspace(); + vm_address_space *addressSpace = vm_kernel_address_space(); vm_translation_map *map = &addressSpace->translation_map; map->ops->lock(map); @@ -366,7 +364,6 @@ block_range::Allocate(block_cache *cache, block_chunk **_chunk) } map->ops->unlock(map); - vm_put_aspace(addressSpace); chunks[chunk].mapped = true; } diff --git a/src/system/kernel/elf.c b/src/system/kernel/elf.c index 0ef7061c09..ac9508eb56 100644 --- a/src/system/kernel/elf.c +++ b/src/system/kernel/elf.c @@ -1008,7 +1008,7 @@ symbol_found: status_t -elf_load_user_image(const char *path, struct team *p, int flags, addr_t *entry) +elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entry) { struct Elf32_Ehdr eheader; struct Elf32_Phdr *pheaders = NULL; @@ -1018,7 +1018,7 @@ elf_load_user_image(const char *path, struct team *p, int flags, addr_t *entry) int i; ssize_t len; - TRACE(("elf_load: entry path '%s', team %p\n", path, p)); + TRACE(("elf_load: entry path '%s', team %p\n", path, team)); fd = _kern_open(-1, path, O_RDONLY, 0); if (fd < 0) @@ -1095,7 +1095,7 @@ elf_load_user_image(const char *path, struct team *p, int flags, addr_t *entry) sprintf(regionName, "%s_seg%drw", baseName, i); - id = vm_map_file(p->aspace->id, regionName, + id = vm_map_file(team->id, regionName, (void **)®ionAddress, B_EXACT_ADDRESS, fileUpperBound, @@ -1128,7 +1128,7 @@ elf_load_user_image(const char *path, struct team *p, int flags, addr_t *entry) sprintf(regionName, "%s_bss%d", baseName, i); regionAddress += fileUpperBound; - id = create_area_etc(p, regionName, (void **)®ionAddress, + id = create_area_etc(team, regionName, (void **)®ionAddress, B_EXACT_ADDRESS, bss_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (id < B_OK) { dprintf("error allocating bss area: %s!\n", strerror(id)); @@ -1142,7 +1142,7 @@ elf_load_user_image(const char *path, struct team *p, int flags, addr_t *entry) */ sprintf(regionName, "%s_seg%dro", baseName, i); - id = vm_map_file(p->aspace->id, regionName, + id = vm_map_file(team->id, regionName, (void **)®ionAddress, B_EXACT_ADDRESS, ROUNDUP(pheaders[i].p_memsz + (pheaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE), @@ -1279,7 +1279,7 @@ load_kernel_add_on(const char *path) } // reserve that space and allocate the areas from that one - if (vm_reserve_address_range(vm_get_kernel_aspace_id(), &reservedAddress, + if (vm_reserve_address_range(vm_kernel_address_space_id(), &reservedAddress, B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) goto error3; @@ -1394,7 +1394,7 @@ error5: delete_area(image->data_region.id); delete_area(image->text_region.id); error4: - vm_unreserve_address_range(vm_get_kernel_aspace_id(), reservedAddress, reservedSize); + vm_unreserve_address_range(vm_kernel_address_space_id(), reservedAddress, reservedSize); error3: free(pheaders); error2: diff --git a/src/system/kernel/team.c b/src/system/kernel/team.c index 710f2ec5ba..722de94efe 100644 --- a/src/system/kernel/team.c +++ b/src/system/kernel/team.c @@ -105,9 +105,8 @@ _dump_team_info(struct team *team) kprintf("state: %d\n", team->state); kprintf("pending_signals: 0x%x\n", team->pending_signals); kprintf("io_context: %p\n", team->io_context); - if (team->aspace) - kprintf("aspace: %p (id = 0x%lx)\n", team->aspace, team->aspace->id); - kprintf("kaspace: %p\n", team->kaspace); + if (team->address_space) + kprintf("address_space: %p (id = 0x%lx)\n", team->address_space, team->address_space->id); kprintf("main_thread: %p\n", team->main_thread); kprintf("thread_list: %p\n", team->thread_list); } @@ -661,8 +660,7 @@ team_get_address_space(team_id id, vm_address_space **_addressSpace) if (id == 1) { // we're the kernel team, so we don't have to go through all // the hassle (locking and hash lookup) - atomic_add(&kernel_team->kaspace->ref_count, 1); - *_addressSpace = kernel_team->kaspace; + *_addressSpace = vm_get_kernel_address_space(); return B_OK; } @@ -671,8 +669,8 @@ team_get_address_space(team_id id, vm_address_space **_addressSpace) team = team_get_team_struct_locked(id); if (team != NULL) { - atomic_add(&team->aspace->ref_count, 1); - *_addressSpace = team->aspace; + atomic_add(&team->address_space->ref_count, 1); + *_addressSpace = team->address_space; status = B_OK; } else status = B_BAD_VALUE; @@ -696,9 +694,7 @@ create_team_struct(const char *name, bool kernel) strlcpy(team->name, name, B_OS_NAME_LENGTH); team->num_threads = 0; team->io_context = NULL; - team->aspace = NULL; - team->kaspace = vm_get_kernel_aspace(); - vm_put_aspace(team->kaspace); + team->address_space = NULL; team->thread_list = NULL; team->main_thread = NULL; team->loading_info = NULL; @@ -885,7 +881,7 @@ team_delete_team(struct team *team) // free team resources - vm_delete_aspace(team->aspace); + vm_delete_address_space(team->address_space); delete_owned_ports(teamID); sem_delete_owned_sems(teamID); remove_images(team); @@ -1149,7 +1145,8 @@ load_image_etc(int32 argCount, char * const *args, int32 envCount, char * const } // create an address space for this team - status = vm_create_aspace(team->name, team->id, USER_BASE, USER_SIZE, false, &team->aspace); + status = vm_create_address_space(team->id, USER_BASE, USER_SIZE, false, + &team->address_space); if (status < B_OK) goto err3; @@ -1211,7 +1208,7 @@ load_image_etc(int32 argCount, char * const *args, int32 envCount, char * const return thread; err4: - vm_put_aspace(team->aspace); + vm_put_address_space(team->address_space); err3: vfs_free_io_context(team->io_context); err2: @@ -1306,7 +1303,7 @@ exec_team(const char *path, int32 argCount, char * const *args, user_debug_prepare_for_exec(); - vm_delete_areas(team->aspace); + vm_delete_areas(team->address_space); delete_owned_ports(team->id); sem_delete_owned_sems(team->id); remove_images(team); @@ -1422,7 +1419,8 @@ fork_team(void) } // create an address space for this team - status = vm_create_aspace(team->name, team->id, USER_BASE, USER_SIZE, false, &team->aspace); + status = vm_create_address_space(team->id, USER_BASE, USER_SIZE, false, + &team->address_space); if (status < B_OK) goto err3; @@ -1433,7 +1431,7 @@ fork_team(void) cookie = 0; while (get_next_area_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { void *address; - area_id area = vm_copy_area(team->aspace->id, info.name, &address, B_CLONE_ADDRESS, + area_id area = vm_copy_area(team->address_space->id, info.name, &address, B_CLONE_ADDRESS, info.protection, info.area); if (area < B_OK) { status = area; @@ -1469,7 +1467,7 @@ fork_team(void) return threadID; err4: - vm_delete_aspace(team->aspace); + vm_delete_address_space(team->address_space); err3: vfs_free_io_context(team->io_context); err2: diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index d5299620e0..ada2db9f3b 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -918,7 +918,7 @@ thread_exit(void) cancel_timer(&thread->alarm); // delete the user stack area first, we won't need it anymore - if (team->aspace != NULL && thread->user_stack_area >= 0) { + if (team->address_space != NULL && thread->user_stack_area >= 0) { area_id area = thread->user_stack_area; thread->user_stack_area = -1; delete_area_etc(team, area); @@ -977,7 +977,7 @@ thread_exit(void) } RELEASE_TEAM_LOCK(); // swap address spaces, to make sure we're running on the kernel's pgdir - vm_aspace_swap(team_get_kernel_team()->kaspace); + vm_swap_address_space(vm_kernel_address_space()); restore_interrupts(state); TRACE(("thread_exit: thread 0x%lx now a kernel thread!\n", thread->id)); diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 5e95a37756..ec717d0a2f 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -67,11 +67,11 @@ static off_t sAvailableMemory; static benaphore sAvailableMemoryLock; // function declarations -static vm_area *_vm_create_region_struct(vm_address_space *aspace, const char *name, int wiring, int lock); -static status_t map_backing_store(vm_address_space *aspace, vm_store *store, void **vaddr, +static vm_area *_vm_create_region_struct(vm_address_space *addressSpace, const char *name, int wiring, int lock); +static status_t map_backing_store(vm_address_space *addressSpace, vm_store *store, void **vaddr, off_t offset, addr_t size, uint32 addressSpec, int wiring, int lock, int mapping, vm_area **_area, const char *area_name); static status_t vm_soft_fault(addr_t address, bool is_write, bool is_user); -static vm_area *vm_virtual_map_lookup(vm_virtual_map *map, addr_t address); +static vm_area *vm_area_lookup(vm_address_space *addressSpace, addr_t address); static bool vm_put_area(vm_area *area); @@ -119,7 +119,7 @@ vm_get_area(area_id id) static vm_area * -_vm_create_reserved_region_struct(vm_virtual_map *map, uint32 flags) +_vm_create_reserved_region_struct(vm_address_space *addressSpace, uint32 flags) { vm_area *reserved = (vm_area *)malloc(sizeof(vm_area)); if (reserved == NULL) @@ -129,14 +129,14 @@ _vm_create_reserved_region_struct(vm_virtual_map *map, uint32 flags) reserved->id = RESERVED_AREA_ID; // this marks it as reserved space reserved->protection = flags; - reserved->map = map; + reserved->address_space = addressSpace; return reserved; } static vm_area * -_vm_create_area_struct(vm_address_space *aspace, const char *name, +_vm_create_area_struct(vm_address_space *addressSpace, const char *name, uint32 wiring, uint32 protection) { vm_area *area = NULL; @@ -168,9 +168,8 @@ _vm_create_area_struct(vm_address_space *aspace, const char *name, area->cache_ref = NULL; area->cache_offset = 0; - area->aspace = aspace; - area->aspace_next = NULL; - area->map = &aspace->virtual_map; + area->address_space = addressSpace; + area->address_space_next = NULL; area->cache_next = area->cache_prev = NULL; area->hash_next = NULL; @@ -184,11 +183,12 @@ _vm_create_area_struct(vm_address_space *aspace, const char *name, */ static status_t -find_reserved_area(vm_virtual_map *map, addr_t start, addr_t size, vm_area *area) +find_reserved_area(vm_address_space *addressSpace, addr_t start, + addr_t size, vm_area *area) { vm_area *next, *last = NULL; - next = map->areas; + next = addressSpace->areas; while (next) { if (next->base <= start && next->base + next->size >= start + size) { // this area covers the requested range @@ -200,7 +200,7 @@ find_reserved_area(vm_virtual_map *map, addr_t start, addr_t size, vm_area *area break; } last = next; - next = next->aspace_next; + next = next->address_space_next; } if (next == NULL) return B_ENTRY_NOT_FOUND; @@ -212,37 +212,38 @@ find_reserved_area(vm_virtual_map *map, addr_t start, addr_t size, vm_area *area if (start == next->base) { // the area starts at the beginning of the reserved range if (last) - last->aspace_next = area; + last->address_space_next = area; else - map->areas = area; + addressSpace->areas = area; if (size == next->size) { // the new area fully covers the reversed range - area->aspace_next = next->aspace_next; + area->address_space_next = next->address_space_next; free(next); } else { // resize the reserved range behind the area - area->aspace_next = next; + area->address_space_next = next; next->base += size; next->size -= size; } } else if (start + size == next->base + next->size) { // the area is at the end of the reserved range - area->aspace_next = next->aspace_next; - next->aspace_next = area; + area->address_space_next = next->address_space_next; + next->address_space_next = area; // resize the reserved range before the area next->size = start - next->base; } else { // the area splits the reserved range into two separate ones // we need a new reserved area to cover this space - vm_area *reserved = _vm_create_reserved_region_struct(map, next->protection); + vm_area *reserved = _vm_create_reserved_region_struct(addressSpace, + next->protection); if (reserved == NULL) return B_NO_MEMORY; - reserved->aspace_next = next->aspace_next; - area->aspace_next = reserved; - next->aspace_next = area; + reserved->address_space_next = next->address_space_next; + area->address_space_next = reserved; + next->address_space_next = area; // resize regions reserved->size = next->base + next->size - start - size; @@ -253,17 +254,17 @@ find_reserved_area(vm_virtual_map *map, addr_t start, addr_t size, vm_area *area area->base = start; area->size = size; - map->change_count++; + addressSpace->change_count++; return B_OK; } -// must be called with this address space's virtual_map.sem held +/** must be called with this address space's sem held */ static status_t -find_and_insert_area_slot(vm_virtual_map *map, addr_t start, addr_t size, addr_t end, - uint32 addressSpec, vm_area *area) +find_and_insert_area_slot(vm_address_space *addressSpace, addr_t start, + addr_t size, addr_t end, uint32 addressSpec, vm_area *area) { vm_area *last = NULL; vm_area *next; @@ -273,14 +274,14 @@ find_and_insert_area_slot(vm_virtual_map *map, addr_t start, addr_t size, addr_t map, start, size, end, addressSpec, area)); // do some sanity checking - if (start < map->base || size == 0 - || (end - 1) > (map->base + (map->size - 1)) + if (start < addressSpace->base || size == 0 + || (end - 1) > (addressSpace->base + (addressSpace->size - 1)) || start + size > end) return B_BAD_ADDRESS; if (addressSpec == B_EXACT_ADDRESS) { // search for a reserved area - status_t status = find_reserved_area(map, start, size, area); + status_t status = find_reserved_area(addressSpace, start, size, area); if (status == B_OK || status == B_BAD_VALUE) return status; @@ -290,14 +291,14 @@ find_and_insert_area_slot(vm_virtual_map *map, addr_t start, addr_t size, addr_t // walk up to the spot where we should start searching second_chance: - next = map->areas; + next = addressSpace->areas; while (next) { if (next->base >= start + size) { // we have a winner break; } last = next; - next = next->aspace_next; + next = next->address_space_next; } // find the right spot depending on the address specification - the area @@ -310,13 +311,13 @@ second_chance: // find a hole big enough for a new area if (!last) { // see if we can build it at the beginning of the virtual map - if (!next || (next->base >= map->base + size)) { + if (!next || (next->base >= addressSpace->base + size)) { foundSpot = true; - area->base = map->base; + area->base = addressSpace->base; break; } last = next; - next = next->aspace_next; + next = next->address_space_next; } // keep walking while (next) { @@ -325,10 +326,11 @@ second_chance: break; } last = next; - next = next->aspace_next; + next = next->address_space_next; } - if ((map->base + (map->size - 1)) >= (last->base + last->size + (size - 1))) { + if ((addressSpace->base + (addressSpace->size - 1)) + >= (last->base + last->size + (size - 1))) { // got a spot foundSpot = true; area->base = last->base + last->size; @@ -338,16 +340,16 @@ second_chance: // the RESERVED_AVOID_BASE flag set, we can now test those for free // space // ToDo: it would make sense to start with the biggest of them - next = map->areas; + next = addressSpace->areas; last = NULL; - for (last = NULL; next; next = next->aspace_next, last = next) { + for (last = NULL; next; next = next->address_space_next, last = next) { // ToDo: take free space after the reserved area into account! if (next->size == size) { // the reserved area is entirely covered, and thus, removed if (last) - last->aspace_next = next->aspace_next; + last->address_space_next = next->address_space_next; else - map->areas = next->aspace_next; + addressSpace->areas = next->address_space_next; foundSpot = true; area->base = next->base; @@ -377,7 +379,7 @@ second_chance: break; } last = next; - next = next->aspace_next; + next = next->address_space_next; } // keep walking while (next) { @@ -386,10 +388,11 @@ second_chance: break; } last = next; - next = next->aspace_next; + next = next->address_space_next; } - if ((map->base + (map->size - 1)) >= (last->base + last->size + (size - 1))) { + if ((addressSpace->base + (addressSpace->size - 1)) + >= (last->base + last->size + (size - 1))) { // got a spot foundSpot = true; if (last->base + last->size <= start) @@ -400,7 +403,7 @@ second_chance: } // we didn't find a free spot in the requested range, so we'll // try again without any restrictions - start = map->base; + start = addressSpace->base; addressSpec = B_ANY_ADDRESS; last = NULL; goto second_chance; @@ -437,22 +440,21 @@ second_chance: area->size = size; if (last) { - area->aspace_next = last->aspace_next; - last->aspace_next = area; + area->address_space_next = last->address_space_next; + last->address_space_next = area; } else { - area->aspace_next = map->areas; - map->areas = area; + area->address_space_next = addressSpace->areas; + addressSpace->areas = area; } - map->change_count++; + addressSpace->change_count++; return B_OK; } -/** This inserts the area you pass into the virtual_map of the - * specified address space. +/** This inserts the area you pass into the specified address space. * It will also set the "_address" argument to its base address when * the call succeeds. - * You need to hold the virtual_map semaphore. + * You need to hold the vm_address_space semaphore. */ static status_t @@ -470,21 +472,21 @@ insert_area(vm_address_space *addressSpace, void **_address, case B_BASE_ADDRESS: searchBase = (addr_t)*_address; - searchEnd = addressSpace->virtual_map.base + (addressSpace->virtual_map.size - 1); + searchEnd = addressSpace->base + (addressSpace->size - 1); break; case B_ANY_ADDRESS: case B_ANY_KERNEL_ADDRESS: case B_ANY_KERNEL_BLOCK_ADDRESS: - searchBase = addressSpace->virtual_map.base; - searchEnd = addressSpace->virtual_map.base + (addressSpace->virtual_map.size - 1); + searchBase = addressSpace->base; + searchEnd = addressSpace->base + (addressSpace->size - 1); break; default: return B_BAD_VALUE; } - status = find_and_insert_area_slot(&addressSpace->virtual_map, searchBase, size, + status = find_and_insert_area_slot(addressSpace, searchBase, size, searchEnd, addressSpec, area); if (status == B_OK) { // ToDo: do we have to do anything about B_ANY_KERNEL_ADDRESS @@ -498,7 +500,7 @@ insert_area(vm_address_space *addressSpace, void **_address, // a ref to the cache holding this store must be held before entering here static status_t -map_backing_store(vm_address_space *aspace, vm_store *store, void **_virtualAddress, +map_backing_store(vm_address_space *addressSpace, vm_store *store, void **_virtualAddress, off_t offset, addr_t size, uint32 addressSpec, int wiring, int protection, int mapping, vm_area **_area, const char *areaName) { @@ -512,9 +514,10 @@ map_backing_store(vm_address_space *aspace, vm_store *store, void **_virtualAddr int err; TRACE(("map_backing_store: aspace %p, store %p, *vaddr %p, offset 0x%Lx, size %lu, addressSpec %ld, wiring %d, protection %d, _area %p, area_name '%s'\n", - aspace, store, *_virtualAddress, offset, size, addressSpec, wiring, protection, _area, areaName)); + addressSpace, store, *_virtualAddress, offset, size, addressSpec, + wiring, protection, _area, areaName)); - area = _vm_create_area_struct(aspace, areaName, wiring, protection); + area = _vm_create_area_struct(addressSpace, areaName, wiring, protection); if (area == NULL) return B_NO_MEMORY; @@ -554,17 +557,17 @@ map_backing_store(vm_address_space *aspace, vm_store *store, void **_virtualAddr vm_cache_acquire_ref(cache_ref, true); - acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, WRITE_COUNT, 0, 0); - // check to see if this aspace has entered DELETE state - if (aspace->state == VM_ASPACE_STATE_DELETION) { - // okay, someone is trying to delete this aspace now, so we can't + // check to see if this address space has entered DELETE state + if (addressSpace->state == VM_ASPACE_STATE_DELETION) { + // okay, someone is trying to delete this address space now, so we can't // insert the area, so back out err = B_BAD_TEAM_ID; goto err1b; } - err = insert_area(aspace, _virtualAddress, addressSpec, size, area); + err = insert_area(addressSpace, _virtualAddress, addressSpec, size, area); if (err < B_OK) goto err1b; @@ -579,16 +582,16 @@ map_backing_store(vm_address_space *aspace, vm_store *store, void **_virtualAddr hash_insert(sAreaHash, area); release_sem_etc(sAreaHashLock, WRITE_COUNT, 0); - // grab a ref to the aspace (the area holds this) - atomic_add(&aspace->ref_count, 1); + // grab a ref to the address space (the area holds this) + atomic_add(&addressSpace->ref_count, 1); - release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); *_area = area; return B_OK; err1b: - release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); vm_cache_release_ref(cache_ref); goto err; err1a: @@ -606,21 +609,21 @@ err: status_t -vm_unreserve_address_range(aspace_id aid, void *address, addr_t size) +vm_unreserve_address_range(team_id team, void *address, addr_t size) { vm_address_space *addressSpace; vm_area *area, *last = NULL; status_t status = B_OK; - addressSpace = vm_get_aspace_by_id(aid); + addressSpace = vm_get_address_space_by_id(team); if (addressSpace == NULL) return B_BAD_TEAM_ID; - acquire_sem_etc(addressSpace->virtual_map.sem, WRITE_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, WRITE_COUNT, 0, 0); - // check to see if this aspace has entered DELETE state + // check to see if this address space has entered DELETE state if (addressSpace->state == VM_ASPACE_STATE_DELETION) { - // okay, someone is trying to delete this aspace now, so we can't + // okay, someone is trying to delete this address space now, so we can't // insert the area, so back out status = B_BAD_TEAM_ID; goto out; @@ -628,7 +631,7 @@ vm_unreserve_address_range(aspace_id aid, void *address, addr_t size) // search area list and remove any matching reserved ranges - area = addressSpace->virtual_map.areas; + area = addressSpace->areas; while (area) { // the area must be completely part of the reserved range if (area->id == RESERVED_AREA_ID && area->base >= (addr_t)address @@ -636,28 +639,28 @@ vm_unreserve_address_range(aspace_id aid, void *address, addr_t size) // remove reserved range vm_area *reserved = area; if (last) - last->aspace_next = reserved->aspace_next; + last->address_space_next = reserved->address_space_next; else - addressSpace->virtual_map.areas = reserved->aspace_next; + addressSpace->areas = reserved->address_space_next; - area = reserved->aspace_next; + area = reserved->address_space_next; free(reserved); continue; } last = area; - area = area->aspace_next; + area = area->address_space_next; } out: - release_sem_etc(addressSpace->virtual_map.sem, WRITE_COUNT, 0); - vm_put_aspace(addressSpace); + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); + vm_put_address_space(addressSpace); return status; } status_t -vm_reserve_address_range(aspace_id aid, void **_address, uint32 addressSpec, +vm_reserve_address_range(team_id team, void **_address, uint32 addressSpec, addr_t size, uint32 flags) { vm_address_space *addressSpace; @@ -667,21 +670,21 @@ vm_reserve_address_range(aspace_id aid, void **_address, uint32 addressSpec, if (size == 0) return B_BAD_VALUE; - addressSpace = vm_get_aspace_by_id(aid); + addressSpace = vm_get_address_space_by_id(team); if (addressSpace == NULL) return B_BAD_TEAM_ID; - area = _vm_create_reserved_region_struct(&addressSpace->virtual_map, flags); + area = _vm_create_reserved_region_struct(addressSpace, flags); if (area == NULL) { status = B_NO_MEMORY; goto err1; } - acquire_sem_etc(addressSpace->virtual_map.sem, WRITE_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, WRITE_COUNT, 0, 0); - // check to see if this aspace has entered DELETE state + // check to see if this address space has entered DELETE state if (addressSpace->state == VM_ASPACE_STATE_DELETION) { - // okay, someone is trying to delete this aspace now, so we can't + // okay, someone is trying to delete this address space now, so we can't // insert the area, let's back out status = B_BAD_TEAM_ID; goto err2; @@ -696,26 +699,26 @@ vm_reserve_address_range(aspace_id aid, void **_address, uint32 addressSpec, area->cache_offset = area->base; // we cache the original base address here - release_sem_etc(addressSpace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); return B_OK; err2: - release_sem_etc(addressSpace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); free(area); err1: - vm_put_aspace(addressSpace); + vm_put_address_space(addressSpace); return status; } area_id -vm_create_anonymous_area(aspace_id aid, const char *name, void **address, +vm_create_anonymous_area(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 wiring, uint32 protection) { vm_area *area; vm_cache *cache; vm_store *store; - vm_address_space *aspace; + vm_address_space *addressSpace; vm_cache_ref *cache_ref; vm_page *page = NULL; bool isStack = (protection & B_STACK_AREA) != 0; @@ -763,8 +766,8 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, return B_BAD_VALUE; } - aspace = vm_get_aspace_by_id(aid); - if (aspace == NULL) + addressSpace = vm_get_address_space_by_id(aid); + if (addressSpace == NULL) return B_BAD_TEAM_ID; size = PAGE_ALIGN(size); @@ -774,7 +777,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, // fail for obvious reasons page = vm_page_allocate_page_run(PAGE_STATE_CLEAR, size / B_PAGE_SIZE); if (page == NULL) { - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return B_NO_MEMORY; } } @@ -807,11 +810,11 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, } vm_cache_acquire_ref(cache_ref, true); - err = map_backing_store(aspace, store, address, 0, size, addressSpec, wiring, + err = map_backing_store(addressSpace, store, address, 0, size, addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name); vm_cache_release_ref(cache_ref); if (err < 0) { - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); if (wiring == B_CONTIGUOUS) { // we had reserved the area space upfront... @@ -861,6 +864,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, // the pages should already be mapped. This is only really useful during // boot time. Find the appropriate vm_page objects and stick them in // the cache object. + vm_translation_map *map = &addressSpace->translation_map; addr_t va; addr_t pa; uint32 flags; @@ -871,9 +875,9 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, panic("ALREADY_WIRED flag used outside kernel startup\n"); mutex_lock(&cache_ref->lock); - (*aspace->translation_map.ops->lock)(&aspace->translation_map); + (*map->ops->lock)(map); for (va = area->base; va < area->base + area->size; va += B_PAGE_SIZE, offset += B_PAGE_SIZE) { - err = (*aspace->translation_map.ops->query)(&aspace->translation_map, va, &pa, &flags); + err = (*map->ops->query)(map, va, &pa, &flags); if (err < 0) { // dprintf("vm_create_anonymous_area: error looking up mapping for va 0x%x\n", va); continue; @@ -887,7 +891,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, vm_page_set_state(page, PAGE_STATE_WIRED); vm_cache_insert_page(cache_ref, page, offset); } - (*aspace->translation_map.ops->unlock)(&aspace->translation_map); + (*map->ops->unlock)(map); mutex_unlock(&cache_ref->lock); break; } @@ -896,22 +900,23 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, { // We have already allocated our continuous pages run, so we can now just // map them in the address space + vm_translation_map *map = &addressSpace->translation_map; addr_t physicalAddress = page->ppn * B_PAGE_SIZE; addr_t virtualAddress; off_t offset = 0; mutex_lock(&cache_ref->lock); - (*aspace->translation_map.ops->lock)(&aspace->translation_map); + (*map->ops->lock)(map); for (virtualAddress = area->base; virtualAddress < area->base + area->size; - virtualAddress += B_PAGE_SIZE, offset += B_PAGE_SIZE, physicalAddress += B_PAGE_SIZE) { + virtualAddress += B_PAGE_SIZE, offset += B_PAGE_SIZE, + physicalAddress += B_PAGE_SIZE) { page = vm_lookup_page(physicalAddress / B_PAGE_SIZE); if (page == NULL) panic("couldn't lookup physical page just allocated\n"); atomic_add(&page->ref_count, 1); - err = (*aspace->translation_map.ops->map)(&aspace->translation_map, - virtualAddress, physicalAddress, protection); + err = (*map->ops->map)(map, virtualAddress, physicalAddress, protection); if (err < 0) panic("couldn't map physical page in page run\n"); @@ -919,7 +924,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, vm_cache_insert_page(cache_ref, page, offset); } - (*aspace->translation_map.ops->unlock)(&aspace->translation_map); + (*map->ops->unlock)(map); mutex_unlock(&cache_ref->lock); break; } @@ -927,7 +932,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, default: break; } - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); TRACE(("vm_create_anonymous_area: done\n")); @@ -939,7 +944,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, area_id -vm_map_physical_memory(aspace_id areaID, const char *name, void **_address, +vm_map_physical_memory(team_id areaID, const char *name, void **_address, uint32 addressSpec, addr_t size, uint32 protection, addr_t physicalAddress) { @@ -949,7 +954,7 @@ vm_map_physical_memory(aspace_id areaID, const char *name, void **_address, vm_store *store; addr_t mapOffset; status_t status; - vm_address_space *aspace = vm_get_aspace_by_id(areaID); + vm_address_space *addressSpace = vm_get_address_space_by_id(areaID); TRACE(("vm_map_physical_memory(aspace = %ld, \"%s\", virtual = %p, spec = %ld," " size = %lu, protection = %ld, phys = %p)\n", @@ -959,7 +964,7 @@ vm_map_physical_memory(aspace_id areaID, const char *name, void **_address, if (!arch_vm_supports_protection(protection)) return B_NOT_SUPPORTED; - if (aspace == NULL) + if (addressSpace == NULL) return B_BAD_TEAM_ID; // if the physical address is somewhat inside a page, @@ -986,7 +991,7 @@ vm_map_physical_memory(aspace_id areaID, const char *name, void **_address, cache->scan_skip = 1; vm_cache_acquire_ref(cacheRef, true); - status = map_backing_store(aspace, store, _address, 0, size, + status = map_backing_store(addressSpace, store, _address, 0, size, addressSpec & ~B_MTR_MASK, 0, protection, REGION_NO_PRIVATE_MAP, &area, name); vm_cache_release_ref(cacheRef); @@ -1002,11 +1007,11 @@ vm_map_physical_memory(aspace_id areaID, const char *name, void **_address, // make sure our area is mapped in completely // (even if that makes the fault routine pretty much useless) for (addr_t offset = 0; offset < size; offset += B_PAGE_SIZE) { - store->ops->fault(store, aspace, offset); + store->ops->fault(store, addressSpace, offset); } } - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); if (status < B_OK) return status; @@ -1019,7 +1024,7 @@ vm_map_physical_memory(aspace_id areaID, const char *name, void **_address, area_id -vm_create_null_area(aspace_id aid, const char *name, void **address, uint32 addressSpec, addr_t size) +vm_create_null_area(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size) { vm_area *area; vm_cache *cache; @@ -1028,8 +1033,8 @@ vm_create_null_area(aspace_id aid, const char *name, void **address, uint32 addr // addr_t map_offset; int err; - vm_address_space *aspace = vm_get_aspace_by_id(aid); - if (aspace == NULL) + vm_address_space *addressSpace = vm_get_address_space_by_id(aid); + if (addressSpace == NULL) return B_BAD_TEAM_ID; size = PAGE_ALIGN(size); @@ -1048,9 +1053,9 @@ vm_create_null_area(aspace_id aid, const char *name, void **address, uint32 addr cache->scan_skip = 1; vm_cache_acquire_ref(cache_ref, true); - err = map_backing_store(aspace, store, address, 0, size, addressSpec, 0, B_KERNEL_READ_AREA, REGION_NO_PRIVATE_MAP, &area, name); + err = map_backing_store(addressSpace, store, address, 0, size, addressSpec, 0, B_KERNEL_READ_AREA, REGION_NO_PRIVATE_MAP, &area, name); vm_cache_release_ref(cache_ref); - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); if (err < 0) return err; @@ -1099,7 +1104,7 @@ vm_create_vnode_cache(void *vnode, struct vm_cache_ref **_cacheRef) */ static area_id -_vm_map_file(aspace_id aid, const char *name, void **_address, uint32 addressSpec, +_vm_map_file(team_id aid, const char *name, void **_address, uint32 addressSpec, size_t size, uint32 protection, uint32 mapping, const char *path, off_t offset, bool kernel) { vm_cache_ref *cacheRef; @@ -1114,8 +1119,8 @@ _vm_map_file(aspace_id aid, const char *name, void **_address, uint32 addressSpe // make it into the mapped copy -- this will need quite some changes // to be done in a nice way - vm_address_space *aspace = vm_get_aspace_by_id(aid); - if (aspace == NULL) + vm_address_space *addressSpace = vm_get_address_space_by_id(aid); + if (addressSpace == NULL) return B_BAD_TEAM_ID; TRACE(("_vm_map_file(\"%s\", offset = %Ld, size = %lu, mapping %ld)\n", path, offset, size, mapping)); @@ -1136,10 +1141,10 @@ _vm_map_file(aspace_id aid, const char *name, void **_address, uint32 addressSpe // below because we'll have to release it later anyway, since we grabbed a ref to the vnode at // vfs_get_vnode_from_path(). This puts the ref counts in sync. vm_cache_acquire_ref(cacheRef, false); - status = map_backing_store(aspace, cacheRef->cache->store, _address, offset, size, + status = map_backing_store(addressSpace, cacheRef->cache->store, _address, offset, size, addressSpec, 0, protection, mapping, &area, name); vm_cache_release_ref(cacheRef); - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); if (status < B_OK) return status; @@ -1149,13 +1154,13 @@ _vm_map_file(aspace_id aid, const char *name, void **_address, uint32 addressSpe err2: vfs_put_vnode(vnode); err1: - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return status; } area_id -vm_map_file(aspace_id aid, const char *name, void **address, uint32 addressSpec, +vm_map_file(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 protection, uint32 mapping, const char *path, off_t offset) { if (!arch_vm_supports_protection(protection)) @@ -1168,50 +1173,51 @@ vm_map_file(aspace_id aid, const char *name, void **address, uint32 addressSpec, // ToDo: create a BeOS style call for this! area_id -_user_vm_map_file(const char *uname, void **uaddress, int addressSpec, - addr_t size, int protection, int mapping, const char *upath, off_t offset) +_user_vm_map_file(const char *userName, void **userAddress, int addressSpec, + addr_t size, int protection, int mapping, const char *userPath, off_t offset) { char name[B_OS_NAME_LENGTH]; char path[B_PATH_NAME_LENGTH]; void *address; - int rc; + area_id area; - if (!IS_USER_ADDRESS(uname) || !IS_USER_ADDRESS(uaddress) || !IS_USER_ADDRESS(upath) - || user_strlcpy(name, uname, B_OS_NAME_LENGTH) < B_OK - || user_strlcpy(path, upath, B_PATH_NAME_LENGTH) < B_OK - || user_memcpy(&address, uaddress, sizeof(address)) < B_OK) + if (!IS_USER_ADDRESS(userName) || !IS_USER_ADDRESS(userAddress) + || !IS_USER_ADDRESS(userPath) + || user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK + || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK + || user_memcpy(&address, userAddress, sizeof(address)) < B_OK) return B_BAD_ADDRESS; // userland created areas can always be accessed by the kernel protection |= B_KERNEL_READ_AREA | (protection & B_WRITE_AREA ? B_KERNEL_WRITE_AREA : 0); - rc = _vm_map_file(vm_get_current_user_aspace_id(), name, &address, addressSpec, size, - protection, mapping, path, offset, false); - if (rc < 0) - return rc; + area = _vm_map_file(vm_current_user_address_space_id(), name, &address, + addressSpec, size, protection, mapping, path, offset, false); + if (area < B_OK) + return area; - if (user_memcpy(uaddress, &address, sizeof(address)) < B_OK) + if (user_memcpy(userAddress, &address, sizeof(address)) < B_OK) return B_BAD_ADDRESS; - return rc; + return area; } area_id -vm_clone_area(aspace_id aid, const char *name, void **address, uint32 addressSpec, +vm_clone_area(team_id team, const char *name, void **address, uint32 addressSpec, uint32 protection, uint32 mapping, area_id sourceID) { vm_area *newArea = NULL; vm_area *sourceArea; status_t status; - vm_address_space *aspace = vm_get_aspace_by_id(aid); - if (aspace == NULL) + vm_address_space *addressSpace = vm_get_address_space_by_id(team); + if (addressSpace == NULL) return B_BAD_TEAM_ID; sourceArea = vm_get_area(sourceID); if (sourceArea == NULL) { - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return B_BAD_VALUE; } @@ -1219,7 +1225,7 @@ vm_clone_area(aspace_id aid, const char *name, void **address, uint32 addressSpe // have been adapted. Maybe it should be part of the kernel settings, // anyway (so that old drivers can always work). #if 0 - if (sourceArea->aspace == kernel_aspace && aspace != kernel_aspace + if (sourceArea->aspace == kernel_aspace && addressSpace != kernel_aspace && !(sourceArea->protection & B_USER_CLONEABLE_AREA)) { // kernel areas must not be cloned in userland, unless explicitly // declared user-cloneable upon construction @@ -1228,14 +1234,14 @@ vm_clone_area(aspace_id aid, const char *name, void **address, uint32 addressSpe #endif { vm_cache_acquire_ref(sourceArea->cache_ref, true); - status = map_backing_store(aspace, sourceArea->cache_ref->cache->store, address, + status = map_backing_store(addressSpace, sourceArea->cache_ref->cache->store, address, sourceArea->cache_offset, sourceArea->size, addressSpec, sourceArea->wiring, protection, mapping, &newArea, name); vm_cache_release_ref(sourceArea->cache_ref); } vm_put_area(sourceArea); - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); if (status < B_OK) return status; @@ -1245,18 +1251,18 @@ vm_clone_area(aspace_id aid, const char *name, void **address, uint32 addressSpe static status_t -_vm_delete_area(vm_address_space *aspace, area_id id) +_vm_delete_area(vm_address_space *addressSpace, area_id id) { status_t status = B_OK; vm_area *area; - TRACE(("vm_delete_area: aspace id 0x%lx, area id 0x%lx\n", aspace->id, id)); + TRACE(("vm_delete_area: aspace id 0x%lx, area id 0x%lx\n", addressSpace->id, id)); area = vm_get_area(id); if (area == NULL) return B_BAD_VALUE; - if (area->aspace == aspace) { + if (area->address_space == addressSpace) { vm_put_area(area); // next put below will actually delete it } else @@ -1268,48 +1274,48 @@ _vm_delete_area(vm_address_space *aspace, area_id id) status_t -vm_delete_area(aspace_id aid, area_id rid) +vm_delete_area(team_id aid, area_id rid) { - vm_address_space *aspace; + vm_address_space *addressSpace; status_t err; - aspace = vm_get_aspace_by_id(aid); - if (aspace == NULL) + addressSpace = vm_get_address_space_by_id(aid); + if (addressSpace == NULL) return B_BAD_TEAM_ID; - err = _vm_delete_area(aspace, rid); - vm_put_aspace(aspace); + err = _vm_delete_area(addressSpace, rid); + vm_put_address_space(addressSpace); return err; } static void -remove_area_from_virtual_map(vm_address_space *addressSpace, vm_area *area, bool locked) +remove_area_from_address_space(vm_address_space *addressSpace, vm_area *area, bool locked) { vm_area *temp, *last = NULL; if (!locked) - acquire_sem_etc(addressSpace->virtual_map.sem, WRITE_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, WRITE_COUNT, 0, 0); - temp = addressSpace->virtual_map.areas; + temp = addressSpace->areas; while (temp != NULL) { if (area == temp) { if (last != NULL) { - last->aspace_next = temp->aspace_next; + last->address_space_next = temp->address_space_next; } else { - addressSpace->virtual_map.areas = temp->aspace_next; + addressSpace->areas = temp->address_space_next; } - addressSpace->virtual_map.change_count++; + addressSpace->change_count++; break; } last = temp; - temp = temp->aspace_next; + temp = temp->address_space_next; } - if (area == addressSpace->virtual_map.area_hint) - addressSpace->virtual_map.area_hint = NULL; + if (area == addressSpace->area_hint) + addressSpace->area_hint = NULL; if (!locked) - release_sem_etc(addressSpace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); if (temp == NULL) panic("vm_area_release_ref: area not found in aspace's area list\n"); @@ -1319,7 +1325,7 @@ remove_area_from_virtual_map(vm_address_space *addressSpace, vm_area *area, bool static bool _vm_put_area(vm_area *area, bool aspaceLocked) { - vm_address_space *aspace; + vm_address_space *addressSpace; bool removeit = false; //TRACE(("_vm_put_area(area = %p, aspaceLocked = %s)\n", @@ -1339,23 +1345,24 @@ _vm_put_area(vm_area *area, bool aspaceLocked) if (!removeit) return false; - aspace = area->aspace; + addressSpace = area->address_space; + // ToDo: do that only for vnode stores vm_cache_write_modified(area->cache_ref); arch_vm_unset_memory_type(area); - remove_area_from_virtual_map(aspace, area, aspaceLocked); + remove_area_from_address_space(addressSpace, area, aspaceLocked); vm_cache_remove_area(area->cache_ref, area); vm_cache_release_ref(area->cache_ref); - (*aspace->translation_map.ops->lock)(&aspace->translation_map); - (*aspace->translation_map.ops->unmap)(&aspace->translation_map, area->base, - area->base + (area->size - 1)); - (*aspace->translation_map.ops->unlock)(&aspace->translation_map); + vm_translation_map *map = &addressSpace->translation_map; + (*map->ops->lock)(map); + (*map->ops->unmap)(map, area->base, area->base + (area->size - 1)); + (*map->ops->unlock)(map); // now we can give up the area's reference to the address space - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); free(area->name); free(area); @@ -1436,7 +1443,7 @@ vm_copy_on_write_area(vm_area *area) // We now need to remap all pages from the area read-only, so that // a copy will be created on next write access - map = &area->aspace->translation_map; + map = &area->address_space->translation_map; map->ops->lock(map); map->ops->unmap(map, area->base, area->base - 1 + area->size); @@ -1461,7 +1468,7 @@ err1: area_id -vm_copy_area(aspace_id addressSpaceID, const char *name, void **_address, uint32 addressSpec, +vm_copy_area(team_id addressSpaceID, const char *name, void **_address, uint32 addressSpec, uint32 protection, area_id sourceID) { vm_address_space *addressSpace; @@ -1480,7 +1487,7 @@ vm_copy_area(aspace_id addressSpaceID, const char *name, void **_address, uint32 if ((source = vm_get_area(sourceID)) == NULL) return B_BAD_VALUE; - addressSpace = vm_get_aspace_by_id(addressSpaceID); + addressSpace = vm_get_address_space_by_id(addressSpaceID); cacheRef = source->cache_ref; if (addressSpec == B_CLONE_ADDRESS) { @@ -1510,7 +1517,7 @@ vm_copy_area(aspace_id addressSpaceID, const char *name, void **_address, uint32 status = target->id; err: - vm_put_aspace(addressSpace); + vm_put_address_space(addressSpace); vm_put_area(source); return status; @@ -1534,7 +1541,7 @@ count_writable_areas(vm_cache_ref *ref, vm_area *ignoreArea) static status_t -vm_set_area_protection(aspace_id aspaceID, area_id areaID, uint32 newProtection) +vm_set_area_protection(team_id aspaceID, area_id areaID, uint32 newProtection) { vm_cache_ref *cacheRef; vm_cache *cache; @@ -1551,7 +1558,7 @@ vm_set_area_protection(aspace_id aspaceID, area_id areaID, uint32 newProtection) if (area == NULL) return B_BAD_VALUE; - if (aspaceID != vm_get_kernel_aspace_id() && area->aspace->id != aspaceID) { + if (aspaceID != vm_kernel_address_space_id() && area->address_space->id != aspaceID) { // unless you're the kernel, you are only allowed to set // the protection of your own areas vm_put_area(area); @@ -1613,7 +1620,7 @@ vm_set_area_protection(aspace_id aspaceID, area_id areaID, uint32 newProtection) if (status == B_OK && area->protection != newProtection) { // remap existing pages in this cache - struct vm_translation_map *map = &area->aspace->translation_map; + struct vm_translation_map *map = &area->address_space->translation_map; map->ops->lock(map); map->ops->protect(map, area->base, area->base + area->size, newProtection); @@ -1630,20 +1637,20 @@ vm_set_area_protection(aspace_id aspaceID, area_id areaID, uint32 newProtection) status_t -vm_get_page_mapping(aspace_id aid, addr_t vaddr, addr_t *paddr) +vm_get_page_mapping(team_id aid, addr_t vaddr, addr_t *paddr) { - vm_address_space *aspace; + vm_address_space *addressSpace; uint32 null_flags; status_t err; - aspace = vm_get_aspace_by_id(aid); - if (aspace == NULL) + addressSpace = vm_get_address_space_by_id(aid); + if (addressSpace == NULL) return B_BAD_TEAM_ID; - err = aspace->translation_map.ops->query(&aspace->translation_map, + err = addressSpace->translation_map.ops->query(&addressSpace->translation_map, vaddr, paddr, &null_flags); - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return err; } @@ -1915,26 +1922,26 @@ dump_area_list(int argc, char **argv) status_t -vm_delete_areas(struct vm_address_space *aspace) +vm_delete_areas(struct vm_address_space *addressSpace) { vm_area *area; vm_area *next, *last = NULL; - TRACE(("vm_delete_areas: called on aspace 0x%lx\n", aspace->id)); + TRACE(("vm_delete_areas: called on aspace 0x%lx\n", addressSpace->id)); - acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, WRITE_COUNT, 0, 0); // remove all reserved areas in this address space - for (area = aspace->virtual_map.areas; area; area = next) { - next = area->aspace_next; + for (area = addressSpace->areas; area; area = next) { + next = area->address_space_next; if (area->id == RESERVED_AREA_ID) { // just remove it if (last) - last->aspace_next = area->aspace_next; + last->address_space_next = area->address_space_next; else - aspace->virtual_map.areas = area->aspace_next; + addressSpace->areas = area->address_space_next; free(area); continue; @@ -1943,10 +1950,10 @@ vm_delete_areas(struct vm_address_space *aspace) last = area; } - // delete all the areas in this aspace + // delete all the areas in this address space - for (area = aspace->virtual_map.areas; area; area = next) { - next = area->aspace_next; + for (area = addressSpace->areas; area; area = next) { + next = area->address_space_next; // decrement the ref on this area, may actually push the ref < 0, if there // is a concurrent delete_area() on that specific area, but that's ok here @@ -1954,27 +1961,27 @@ vm_delete_areas(struct vm_address_space *aspace) dprintf("vm_delete_areas() did not delete area %p\n", area); } - release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); return B_OK; } static area_id -vm_area_for(aspace_id aid, addr_t address) +vm_area_for(team_id team, addr_t address) { vm_address_space *addressSpace; area_id id = B_ERROR; vm_area *area; - addressSpace = vm_get_aspace_by_id(aid); + addressSpace = vm_get_address_space_by_id(team); if (addressSpace == NULL) return B_BAD_TEAM_ID; - acquire_sem_etc(addressSpace->virtual_map.sem, READ_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, READ_COUNT, 0, 0); - area = addressSpace->virtual_map.areas; - for (; area != NULL; area = area->aspace_next) { + area = addressSpace->areas; + for (; area != NULL; area = area->address_space_next) { // ignore reserved space regions if (area->id == RESERVED_AREA_ID) continue; @@ -1985,8 +1992,8 @@ vm_area_for(aspace_id aid, addr_t address) } } - release_sem_etc(addressSpace->virtual_map.sem, READ_COUNT, 0); - vm_put_aspace(addressSpace); + release_sem_etc(addressSpace->sem, READ_COUNT, 0); + vm_put_address_space(addressSpace); return id; } @@ -2029,7 +2036,7 @@ vm_free_unused_boot_loader_range(addr_t start, addr_t size) map->ops->lock(map); - for (area = kernel_aspace->virtual_map.areas; area; area = area->aspace_next) { + for (area = kernel_aspace->areas; area; area = area->address_space_next) { addr_t areaStart = area->base; addr_t areaEnd = areaStart + area->size; @@ -2139,7 +2146,7 @@ unreserve_boot_loader_ranges(kernel_args *args) TRACE(("unreserve_boot_loader_ranges()\n")); for (i = 0; i < args->num_virtual_allocated_ranges; i++) { - vm_unreserve_address_range(vm_get_kernel_aspace_id(), + vm_unreserve_address_range(vm_kernel_address_space_id(), (void *)args->virtual_allocated_range[i].start, args->virtual_allocated_range[i].size); } @@ -2155,7 +2162,7 @@ reserve_boot_loader_ranges(kernel_args *args) for (i = 0; i < args->num_virtual_allocated_ranges; i++) { void *address = (void *)args->virtual_allocated_range[i].start; - status_t status = vm_reserve_address_range(vm_get_kernel_aspace_id(), &address, + status_t status = vm_reserve_address_range(vm_kernel_address_space_id(), &address, B_EXACT_ADDRESS, args->virtual_allocated_range[i].size, 0); if (status < B_OK) panic("could not reserve boot loader ranges\n"); @@ -2200,7 +2207,7 @@ vm_init(kernel_args *args) panic("vm_init: error creating aspace hash table\n"); } - vm_aspace_init(); + vm_address_space_init(); reserve_boot_loader_ranges(args); // do any further initialization that the architecture dependant layers may need now @@ -2236,8 +2243,9 @@ vm_init(kernel_args *args) } { void *null; - vm_map_physical_memory(vm_get_kernel_aspace_id(), "bootdir", &null, B_ANY_KERNEL_ADDRESS, - args->bootdir_addr.size, B_KERNEL_READ_AREA, args->bootdir_addr.start); + vm_map_physical_memory(vm_kernel_address_space_id(), "bootdir", &null, + B_ANY_KERNEL_ADDRESS, args->bootdir_addr.size, B_KERNEL_READ_AREA, + args->bootdir_addr.start); } // add some debugger commands @@ -2271,9 +2279,9 @@ vm_init_post_sem(kernel_args *args) benaphore_init(&sAvailableMemoryLock, "available memory lock"); arch_vm_translation_map_init_post_sem(args); - vm_aspace_init_post_sem(); + vm_address_space_init_post_sem(); - for (area = kernel_aspace->virtual_map.areas; area; area = area->aspace_next) { + for (area = kernel_aspace->areas; area; area = area->address_space_next) { if (area->id == RESERVED_AREA_ID) continue; @@ -2351,12 +2359,11 @@ vm_page_fault(addr_t address, addr_t fault_address, bool is_write, bool is_user, } else { #if 1 // ToDo: remove me once we have proper userland debugging support (and tools) - vm_address_space *aspace = vm_get_current_user_aspace(); - vm_virtual_map *map = &aspace->virtual_map; + vm_address_space *addressSpace = vm_get_current_user_address_space(); vm_area *area; - acquire_sem_etc(map->sem, READ_COUNT, 0, 0); - area = vm_virtual_map_lookup(map, fault_address); + acquire_sem_etc(addressSpace->sem, READ_COUNT, 0, 0); + area = vm_area_lookup(addressSpace, fault_address); dprintf("vm_page_fault: sending team 0x%lx SIGSEGV, ip %#lx (\"%s\" +%#lx)\n", thread_get_current_thread()->team->id, fault_address, @@ -2380,7 +2387,7 @@ vm_page_fault(addr_t address, addr_t fault_address, bool is_write, bool is_user, dprintf("stack trace:\n"); for (; frame; frame = frame->previous) { dprintf(" 0x%p", frame->return_address); - area = vm_virtual_map_lookup(map, + area = vm_area_lookup(map, (addr_t)frame->return_address); if (area) { dprintf(" (%s + %#lx)", area->name, @@ -2391,8 +2398,8 @@ vm_page_fault(addr_t address, addr_t fault_address, bool is_write, bool is_user, } #endif // 0 (stack trace) - release_sem_etc(map->sem, READ_COUNT, 0); - vm_put_aspace(aspace); + release_sem_etc(addressSpace->sem, READ_COUNT, 0); + vm_put_address_space(addressSpace); #endif if (user_debug_exception_occurred(B_SEGMENT_VIOLATION, SIGSEGV)) send_signal(team_get_current_team_id(), SIGSEGV); @@ -2406,8 +2413,7 @@ vm_page_fault(addr_t address, addr_t fault_address, bool is_write, bool is_user, static status_t vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) { - vm_address_space *aspace; - vm_virtual_map *map; + vm_address_space *addressSpace; vm_area *area; vm_cache_ref *cache_ref; vm_cache_ref *last_cache_ref; @@ -2425,10 +2431,10 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) address = ROUNDOWN(originalAddress, B_PAGE_SIZE); if (IS_KERNEL_ADDRESS(address)) { - aspace = vm_get_kernel_aspace(); + addressSpace = vm_get_kernel_address_space(); } else if (IS_USER_ADDRESS(address)) { - aspace = vm_get_current_user_aspace(); - if (aspace == NULL) { + addressSpace = vm_get_current_user_address_space(); + if (addressSpace == NULL) { if (isUser == false) { dprintf("vm_soft_fault: kernel thread accessing invalid user memory!\n"); return B_BAD_ADDRESS; @@ -2442,31 +2448,33 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) // this keeps a user space thread from passing a buffer that crosses into kernel space return B_BAD_ADDRESS; } - map = &aspace->virtual_map; - atomic_add(&aspace->fault_count, 1); + + atomic_add(&addressSpace->fault_count, 1); // Get the area the fault was in - acquire_sem_etc(map->sem, READ_COUNT, 0, 0); - area = vm_virtual_map_lookup(map, address); + acquire_sem_etc(addressSpace->sem, READ_COUNT, 0, 0); + area = vm_area_lookup(addressSpace, address); if (area == NULL) { - release_sem_etc(map->sem, READ_COUNT, 0); - vm_put_aspace(aspace); - dprintf("vm_soft_fault: va 0x%lx not covered by area in address space\n", originalAddress); + release_sem_etc(addressSpace->sem, READ_COUNT, 0); + vm_put_address_space(addressSpace); + dprintf("vm_soft_fault: va 0x%lx not covered by area in address space\n", + originalAddress); return B_BAD_ADDRESS; } // check permissions if (isUser && (area->protection & B_USER_PROTECTION) == 0) { - release_sem_etc(map->sem, READ_COUNT, 0); - vm_put_aspace(aspace); + release_sem_etc(addressSpace->sem, READ_COUNT, 0); + vm_put_address_space(addressSpace); dprintf("user access on kernel area 0x%lx at %p\n", area->id, (void *)originalAddress); return B_PERMISSION_DENIED; } if (isWrite && (area->protection & (B_WRITE_AREA | (isUser ? 0 : B_KERNEL_WRITE_AREA))) == 0) { - release_sem_etc(map->sem, READ_COUNT, 0); - vm_put_aspace(aspace); - dprintf("write access attempted on read-only area 0x%lx at %p\n", area->id, (void *)originalAddress); + release_sem_etc(addressSpace->sem, READ_COUNT, 0); + vm_put_address_space(addressSpace); + dprintf("write access attempted on read-only area 0x%lx at %p\n", + area->id, (void *)originalAddress); return B_PERMISSION_DENIED; } @@ -2476,18 +2484,18 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) top_cache_ref = area->cache_ref; cache_offset = address - area->base + area->cache_offset; vm_cache_acquire_ref(top_cache_ref, true); - change_count = map->change_count; - release_sem_etc(map->sem, READ_COUNT, 0); + change_count = addressSpace->change_count; + release_sem_etc(addressSpace->sem, READ_COUNT, 0); // See if this cache has a fault handler - this will do all the work for us if (top_cache_ref->cache->store->ops->fault != NULL) { // Note, since the page fault is resolved with interrupts enabled, the // fault handler could be called more than once for the same reason - // the store must take this into account - status_t status = (*top_cache_ref->cache->store->ops->fault)(top_cache_ref->cache->store, aspace, cache_offset); + status_t status = (*top_cache_ref->cache->store->ops->fault)(top_cache_ref->cache->store, addressSpace, cache_offset); if (status != B_BAD_HANDLER) { vm_cache_release_ref(top_cache_ref); - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return status; } } @@ -2543,10 +2551,10 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) mutex_unlock(&cache_ref->lock); page = vm_page_allocate_page(PAGE_STATE_FREE); - aspace->translation_map.ops->get_physical_page(page->ppn * B_PAGE_SIZE, (addr_t *)&vec.iov_base, PHYSICAL_PAGE_CAN_WAIT); + addressSpace->translation_map.ops->get_physical_page(page->ppn * B_PAGE_SIZE, (addr_t *)&vec.iov_base, PHYSICAL_PAGE_CAN_WAIT); // ToDo: handle errors here err = cache_ref->cache->store->ops->read(cache_ref->cache->store, cache_offset, &vec, 1, &bytesRead); - aspace->translation_map.ops->put_physical_page((addr_t)vec.iov_base); + addressSpace->translation_map.ops->put_physical_page((addr_t)vec.iov_base); mutex_lock(&cache_ref->lock); @@ -2608,25 +2616,27 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) vm_page *src_page = page; void *src, *dest; + // ToDo: if memory is low, it might be a good idea to steal the page + // from our source cache - if possible, that is FTRACE(("get new page, copy it, and put it into the topmost cache\n")); page = vm_page_allocate_page(PAGE_STATE_FREE); // try to get a mapping for the src and dest page so we can copy it for (;;) { - (*aspace->translation_map.ops->get_physical_page)(src_page->ppn * B_PAGE_SIZE, (addr_t *)&src, PHYSICAL_PAGE_CAN_WAIT); - err = (*aspace->translation_map.ops->get_physical_page)(page->ppn * B_PAGE_SIZE, (addr_t *)&dest, PHYSICAL_PAGE_NO_WAIT); + (*addressSpace->translation_map.ops->get_physical_page)(src_page->ppn * B_PAGE_SIZE, (addr_t *)&src, PHYSICAL_PAGE_CAN_WAIT); + err = (*addressSpace->translation_map.ops->get_physical_page)(page->ppn * B_PAGE_SIZE, (addr_t *)&dest, PHYSICAL_PAGE_NO_WAIT); if (err == B_NO_ERROR) break; // it couldn't map the second one, so sleep and retry // keeps an extremely rare deadlock from occuring - (*aspace->translation_map.ops->put_physical_page)((addr_t)src); + (*addressSpace->translation_map.ops->put_physical_page)((addr_t)src); snooze(5000); } memcpy(dest, src, B_PAGE_SIZE); - (*aspace->translation_map.ops->put_physical_page)((addr_t)src); - (*aspace->translation_map.ops->put_physical_page)((addr_t)dest); + (*addressSpace->translation_map.ops->put_physical_page)((addr_t)src); + (*addressSpace->translation_map.ops->put_physical_page)((addr_t)dest); vm_page_set_state(src_page, PAGE_STATE_ACTIVE); @@ -2654,10 +2664,10 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) } err = B_OK; - acquire_sem_etc(map->sem, READ_COUNT, 0, 0); - if (change_count != map->change_count) { + acquire_sem_etc(addressSpace->sem, READ_COUNT, 0, 0); + if (change_count != addressSpace->change_count) { // something may have changed, see if the address is still valid - area = vm_virtual_map_lookup(map, address); + area = vm_area_lookup(addressSpace, address); if (area == NULL || area->cache_ref != top_cache_ref || (address - area->base + area->cache_offset) != cache_offset) { @@ -2676,13 +2686,13 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) newProtection &= ~(isUser ? B_WRITE_AREA : B_KERNEL_WRITE_AREA); atomic_add(&page->ref_count, 1); - (*aspace->translation_map.ops->lock)(&aspace->translation_map); - (*aspace->translation_map.ops->map)(&aspace->translation_map, address, + (*addressSpace->translation_map.ops->lock)(&addressSpace->translation_map); + (*addressSpace->translation_map.ops->map)(&addressSpace->translation_map, address, page->ppn * B_PAGE_SIZE, newProtection); - (*aspace->translation_map.ops->unlock)(&aspace->translation_map); + (*addressSpace->translation_map.ops->unlock)(&addressSpace->translation_map); } - release_sem_etc(map->sem, READ_COUNT, 0); + release_sem_etc(addressSpace->sem, READ_COUNT, 0); if (dummy_page.state == PAGE_STATE_BUSY) { // We still have the dummy page in the cache - that happens if we didn't need @@ -2697,23 +2707,23 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser) vm_page_set_state(page, PAGE_STATE_ACTIVE); vm_cache_release_ref(top_cache_ref); - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return err; } static vm_area * -vm_virtual_map_lookup(vm_virtual_map *map, addr_t address) +vm_area_lookup(vm_address_space *addressSpace, addr_t address) { vm_area *area; // check the areas list first - area = map->area_hint; + area = addressSpace->area_hint; if (area && area->base <= address && (area->base + area->size) > address) return area; - for (area = map->areas; area != NULL; area = area->aspace_next) { + for (area = addressSpace->areas; area != NULL; area = area->address_space_next) { if (area->id == RESERVED_AREA_ID) continue; @@ -2722,7 +2732,7 @@ vm_virtual_map_lookup(vm_virtual_map *map, addr_t address) } if (area) - map->area_hint = area; + addressSpace->area_hint = area; return area; } @@ -2845,7 +2855,7 @@ user_memset(void *s, char c, size_t count) long lock_memory(void *address, ulong numBytes, ulong flags) { - vm_address_space *aspace = NULL; + vm_address_space *addressSpace = NULL; struct vm_translation_map *map; addr_t base = (addr_t)address; addr_t end = base + numBytes; @@ -2865,13 +2875,13 @@ lock_memory(void *address, ulong numBytes, ulong flags) return B_OK; if (isUser) - aspace = vm_get_current_user_aspace(); + addressSpace = vm_get_current_user_address_space(); else - aspace = vm_get_kernel_aspace(); - if (aspace == NULL) + addressSpace = vm_get_kernel_address_space(); + if (addressSpace == NULL) return B_ERROR; - map = &aspace->translation_map; + map = &addressSpace->translation_map; for (; base < end; base += B_PAGE_SIZE) { addr_t physicalAddress; @@ -2895,12 +2905,12 @@ lock_memory(void *address, ulong numBytes, ulong flags) if (status != B_OK) { dprintf("lock_memory(address = %p, numBytes = %lu, flags = %lu) failed: %s\n", address, numBytes, flags, strerror(status)); - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return status; } } - vm_put_aspace(aspace); + vm_put_address_space(addressSpace); return B_OK; } @@ -2935,9 +2945,9 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table, long // in which address space is the address to be found? if (IS_USER_ADDRESS(virtualAddress)) - addressSpace = vm_get_current_user_aspace(); + addressSpace = vm_get_current_user_address_space(); else - addressSpace = vm_get_kernel_aspace(); + addressSpace = vm_get_kernel_address_space(); if (addressSpace == NULL) return B_ERROR; @@ -2997,7 +3007,7 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table, long area_id area_for(void *address) { - return vm_area_for(vm_get_kernel_aspace_id(), (addr_t)address); + return vm_area_for(vm_kernel_address_space_id(), (addr_t)address); } @@ -3037,7 +3047,7 @@ fill_area_info(struct vm_area *area, area_info *info, size_t size) info->size = area->size; info->protection = area->protection & B_USER_PROTECTION; info->lock = B_FULL_LOCK; - info->team = area->aspace->id; + info->team = area->address_space->id; info->ram_size = area->size; info->copy_count = 0; info->in_count = 0; @@ -3083,9 +3093,9 @@ _get_next_area_info(team_id team, int32 *cookie, area_info *info, size_t size) || team_get_address_space(team, &addressSpace) != B_OK) return B_BAD_VALUE; - acquire_sem_etc(addressSpace->virtual_map.sem, READ_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, READ_COUNT, 0, 0); - for (area = addressSpace->virtual_map.areas; area; area = area->aspace_next) { + for (area = addressSpace->areas; area; area = area->address_space_next) { if (area->id == RESERVED_AREA_ID) continue; @@ -3097,8 +3107,8 @@ _get_next_area_info(team_id team, int32 *cookie, area_info *info, size_t size) if (area != NULL) area = vm_get_area(area->id); - release_sem_etc(addressSpace->virtual_map.sem, READ_COUNT, 0); - vm_put_aspace(addressSpace); + release_sem_etc(addressSpace->sem, READ_COUNT, 0); + vm_put_address_space(addressSpace); if (area == NULL) { nextBase = (addr_t)-1; @@ -3119,7 +3129,7 @@ set_area_protection(area_id area, uint32 newProtection) { fix_protection(&newProtection); - return vm_set_area_protection(vm_get_kernel_aspace_id(), area, newProtection); + return vm_set_area_protection(vm_kernel_address_space_id(), area, newProtection); } @@ -3158,11 +3168,11 @@ resize_area(area_id areaID, size_t newSize) // We need to check if all areas of this cache can be resized for (current = cache->areas; current; current = current->cache_next) { - if (current->aspace_next && current->aspace_next->base <= (current->base + newSize)) { + if (current->address_space_next && current->address_space_next->base <= (current->base + newSize)) { // if the area was created inside a reserved area, it can also be // resized in that area // ToDo: if there is free space after the reserved area, it could be used as well... - vm_area *next = current->aspace_next; + vm_area *next = current->address_space_next; if (next->id == RESERVED_AREA_ID && next->cache_offset <= current->base && next->base - 1 + next->size >= current->base - 1 + newSize) continue; @@ -3176,14 +3186,14 @@ resize_area(area_id areaID, size_t newSize) // Okay, looks good so far, so let's do it for (current = cache->areas; current; current = current->cache_next) { - if (current->aspace_next && current->aspace_next->base <= (current->base + newSize)) { - vm_area *next = current->aspace_next; + if (current->address_space_next && current->address_space_next->base <= (current->base + newSize)) { + vm_area *next = current->address_space_next; if (next->id == RESERVED_AREA_ID && next->cache_offset <= current->base && next->base - 1 + next->size >= current->base - 1 + newSize) { // resize reserved area addr_t offset = current->base + newSize - next->base; if (next->size <= offset) { - current->aspace_next = next->aspace_next; + current->address_space_next = next->address_space_next; free(next); } else { next->size -= offset; @@ -3199,7 +3209,7 @@ resize_area(area_id areaID, size_t newSize) // we also need to unmap all pages beyond the new size, if the area has shrinked if (newSize < oldSize) { - vm_translation_map *map = ¤t->aspace->translation_map; + vm_translation_map *map = ¤t->address_space->translation_map; map->ops->lock(map); map->ops->unmap(map, current->base + newSize, current->base + oldSize - 1); @@ -3255,23 +3265,23 @@ transfer_area(area_id id, void **_address, uint32 addressSpec, team_id target) // address range so that we can later reclaim it if the // transfer failed. - sourceAddressSpace = area->aspace; + sourceAddressSpace = area->address_space; - reserved = _vm_create_reserved_region_struct(&sourceAddressSpace->virtual_map, 0); + reserved = _vm_create_reserved_region_struct(sourceAddressSpace, 0); if (reserved == NULL) { status = B_NO_MEMORY; goto err2; } - acquire_sem_etc(sourceAddressSpace->virtual_map.sem, WRITE_COUNT, 0, 0); + acquire_sem_etc(sourceAddressSpace->sem, WRITE_COUNT, 0, 0); reservedAddress = (void *)area->base; - remove_area_from_virtual_map(sourceAddressSpace, area, true); + remove_area_from_address_space(sourceAddressSpace, area, true); status = insert_area(sourceAddressSpace, &reservedAddress, B_EXACT_ADDRESS, area->size, reserved); // famous last words: this cannot fail :) - release_sem_etc(sourceAddressSpace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(sourceAddressSpace->sem, WRITE_COUNT, 0); if (status != B_OK) goto err3; @@ -3284,10 +3294,10 @@ transfer_area(area_id id, void **_address, uint32 addressSpec, team_id target) // insert the area into the target address space - acquire_sem_etc(targetAddressSpace->virtual_map.sem, WRITE_COUNT, 0, 0); - // check to see if this aspace has entered DELETE state + acquire_sem_etc(targetAddressSpace->sem, WRITE_COUNT, 0, 0); + // check to see if this address space has entered DELETE state if (targetAddressSpace->state == VM_ASPACE_STATE_DELETION) { - // okay, someone is trying to delete this aspace now, so we can't + // okay, someone is trying to delete this adress space now, so we can't // insert the area, so back out status = B_BAD_TEAM_ID; goto err4; @@ -3298,12 +3308,12 @@ transfer_area(area_id id, void **_address, uint32 addressSpec, team_id target) goto err4; // The area was successfully transferred to the new team when we got here - area->aspace = targetAddressSpace; + area->address_space = targetAddressSpace; - release_sem_etc(targetAddressSpace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(targetAddressSpace->sem, WRITE_COUNT, 0); vm_unreserve_address_range(sourceAddressSpace->id, reservedAddress, area->size); - vm_put_aspace(sourceAddressSpace); + vm_put_address_space(sourceAddressSpace); // we keep the reference of the target address space for the // area, so we only have to put the one from the source vm_put_area(area); @@ -3311,11 +3321,11 @@ transfer_area(area_id id, void **_address, uint32 addressSpec, team_id target) return B_OK; err4: - release_sem_etc(targetAddressSpace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(targetAddressSpace->sem, WRITE_COUNT, 0); err3: // insert the area again into the source address space - acquire_sem_etc(sourceAddressSpace->virtual_map.sem, WRITE_COUNT, 0, 0); - // check to see if this aspace has entered DELETE state + acquire_sem_etc(sourceAddressSpace->sem, WRITE_COUNT, 0, 0); + // check to see if this address space has entered DELETE state if (sourceAddressSpace->state == VM_ASPACE_STATE_DELETION || insert_area(sourceAddressSpace, &reservedAddress, B_EXACT_ADDRESS, area->size, area) != B_OK) { // We can't insert the area anymore - we have to delete it manually @@ -3325,9 +3335,9 @@ err3: free(area); area = NULL; } - release_sem_etc(sourceAddressSpace->virtual_map.sem, WRITE_COUNT, 0); + release_sem_etc(sourceAddressSpace->sem, WRITE_COUNT, 0); err2: - vm_put_aspace(targetAddressSpace); + vm_put_address_space(targetAddressSpace); err1: if (area != NULL) vm_put_area(area); @@ -3344,7 +3354,7 @@ map_physical_memory(const char *name, void *physicalAddress, size_t numBytes, fix_protection(&protection); - return vm_map_physical_memory(vm_get_kernel_aspace_id(), name, _virtualAddress, + return vm_map_physical_memory(vm_kernel_address_space_id(), name, _virtualAddress, addressSpec, numBytes, protection, (addr_t)physicalAddress); } @@ -3356,7 +3366,7 @@ clone_area(const char *name, void **_address, uint32 addressSpec, uint32 protect if ((protection & B_KERNEL_PROTECTION) == 0) protection |= B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA; - return vm_clone_area(vm_get_kernel_aspace_id(), name, _address, addressSpec, + return vm_clone_area(vm_kernel_address_space_id(), name, _address, addressSpec, protection, REGION_NO_PRIVATE_MAP, source); } @@ -3367,8 +3377,8 @@ create_area_etc(struct team *team, const char *name, void **address, uint32 addr { fix_protection(&protection); - return vm_create_anonymous_area(team->aspace->id, (char *)name, address, - addressSpec, size, lock, protection); + return vm_create_anonymous_area(team->id, (char *)name, address, + addressSpec, size, lock, protection); } @@ -3378,22 +3388,22 @@ create_area(const char *name, void **_address, uint32 addressSpec, size_t size, { fix_protection(&protection); - return vm_create_anonymous_area(vm_get_kernel_aspace_id(), (char *)name, _address, - addressSpec, size, lock, protection); + return vm_create_anonymous_area(vm_kernel_address_space_id(), (char *)name, _address, + addressSpec, size, lock, protection); } status_t delete_area_etc(struct team *team, area_id area) { - return vm_delete_area(team->aspace->id, area); + return vm_delete_area(team->id, area); } status_t delete_area(area_id area) { - return vm_delete_area(vm_get_kernel_aspace_id(), area); + return vm_delete_area(vm_kernel_address_space_id(), area); } @@ -3403,7 +3413,7 @@ delete_area(area_id area) status_t _user_init_heap_address_range(addr_t base, addr_t size) { - return vm_reserve_address_range(vm_get_current_user_aspace_id(), (void **)&base, + return vm_reserve_address_range(vm_current_user_address_space_id(), (void **)&base, B_EXACT_ADDRESS, size, RESERVED_AVOID_BASE); } @@ -3411,7 +3421,7 @@ _user_init_heap_address_range(addr_t base, addr_t size) area_id _user_area_for(void *address) { - return vm_area_for(vm_get_current_user_aspace_id(), (addr_t)address); + return vm_area_for(vm_current_user_address_space_id(), (addr_t)address); } @@ -3480,7 +3490,7 @@ _user_set_area_protection(area_id area, uint32 newProtection) fix_protection(&newProtection); - return vm_set_area_protection(vm_get_current_user_aspace_id(), area, + return vm_set_area_protection(vm_current_user_address_space_id(), area, newProtection); } @@ -3547,7 +3557,7 @@ _user_clone_area(const char *userName, void **userAddress, uint32 addressSpec, fix_protection(&protection); - clonedArea = vm_clone_area(vm_get_current_user_aspace_id(), name, &address, + clonedArea = vm_clone_area(vm_current_user_address_space_id(), name, &address, addressSpec, protection, REGION_NO_PRIVATE_MAP, sourceArea); if (clonedArea < B_OK) return clonedArea; @@ -3590,8 +3600,8 @@ _user_create_area(const char *userName, void **userAddress, uint32 addressSpec, fix_protection(&protection); - area = vm_create_anonymous_area(vm_get_current_user_aspace_id(), (char *)name, &address, - addressSpec, size, lock, protection); + area = vm_create_anonymous_area(vm_current_user_address_space_id(), + (char *)name, &address, addressSpec, size, lock, protection); if (area >= B_OK && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) { delete_area(area); @@ -3609,6 +3619,6 @@ _user_delete_area(area_id area) // that you have created yourself from userland. // The documentation to delete_area() explicetly states that this // will be restricted in the future, and so it will. - return vm_delete_area(vm_get_current_user_aspace_id(), area); + return vm_delete_area(vm_current_user_address_space_id(), area); } diff --git a/src/system/kernel/vm/vm_address_space.c b/src/system/kernel/vm/vm_address_space.c index 1c7c914c30..566b76b7d1 100644 --- a/src/system/kernel/vm/vm_address_space.c +++ b/src/system/kernel/vm/vm_address_space.c @@ -58,20 +58,19 @@ _dump_aspace(vm_address_space *aspace) vm_area *area; dprintf("dump of address space at %p:\n", aspace); - dprintf("name: '%s'\n", aspace->name); dprintf("id: 0x%lx\n", aspace->id); dprintf("ref_count: %ld\n", aspace->ref_count); dprintf("fault_count: %ld\n", aspace->fault_count); dprintf("working_set_size: 0x%lx\n", aspace->working_set_size); dprintf("translation_map: %p\n", &aspace->translation_map); - dprintf("virtual_map.base: 0x%lx\n", aspace->virtual_map.base); - dprintf("virtual_map.size: 0x%lx\n", aspace->virtual_map.size); - dprintf("virtual_map.change_count: 0x%x\n", aspace->virtual_map.change_count); - dprintf("virtual_map.sem: 0x%lx\n", aspace->virtual_map.sem); - dprintf("virtual_map.region_hint: %p\n", aspace->virtual_map.area_hint); - dprintf("virtual_map.region_list:\n"); - for (area = aspace->virtual_map.areas; area != NULL; area = area->aspace_next) { - dprintf(" region 0x%lx: ", area->id); + dprintf("base: 0x%lx\n", aspace->base); + dprintf("size: 0x%lx\n", aspace->size); + dprintf("change_count: 0x%lx\n", aspace->change_count); + dprintf("sem: 0x%lx\n", aspace->sem); + dprintf("area_hint: %p\n", aspace->area_hint); + dprintf("area_list:\n"); + for (area = aspace->areas; area != NULL; area = area->address_space_next) { + dprintf(" area 0x%lx: ", area->id); dprintf("base_addr = 0x%lx ", area->base); dprintf("size = 0x%lx ", area->size); dprintf("name = '%s' ", area->name); @@ -91,9 +90,9 @@ dump_aspace(int argc, char **argv) } // if the argument looks like a number, treat it as such - if (isdigit(argv[1][0])) { - unsigned long num = strtoul(argv[1], NULL, 0); - aspace_id id = num; + + { + team_id id = strtoul(argv[1], NULL, 0); aspace = hash_lookup(aspace_table, &id); if (aspace == NULL) { @@ -102,16 +101,6 @@ dump_aspace(int argc, char **argv) _dump_aspace(aspace); } return 0; - } else { - // walk through the aspace list, looking for the arguments as a name - struct hash_iterator iter; - - hash_open(aspace_table, &iter); - while ((aspace = hash_next(aspace_table, &iter)) != NULL) { - if(aspace->name != NULL && strcmp(argv[1], aspace->name) == 0) { - _dump_aspace(aspace); - } - } } return 0; } @@ -123,12 +112,12 @@ dump_aspace_list(int argc, char **argv) vm_address_space *as; struct hash_iterator iter; - dprintf("addr\tid\t%32s\tbase\t\tsize\n", "name"); + dprintf("addr\tid\tbase\t\tsize\n"); hash_open(aspace_table, &iter); while ((as = hash_next(aspace_table, &iter)) != NULL) { - dprintf("%p\t0x%lx\t%32s\t0x%lx\t\t0x%lx\n", - as, as->id, as->name, as->virtual_map.base, as->virtual_map.size); + dprintf("%p\t0x%lx\t0x%lx\t\t0x%lx\n", + as, as->id, as->base, as->size); } hash_close(aspace_table, &iter, false); return 0; @@ -139,7 +128,7 @@ static int aspace_compare(void *_a, const void *key) { vm_address_space *aspace = _a; - const aspace_id *id = key; + const team_id *id = key; if (aspace->id == *id) return 0; @@ -152,7 +141,7 @@ static uint32 aspace_hash(void *_a, const void *key, uint32 range) { vm_address_space *aspace = _a; - const aspace_id *id = key; + const team_id *id = key; if (aspace != NULL) return aspace->id % range; @@ -166,24 +155,23 @@ aspace_hash(void *_a, const void *key, uint32 range) */ static void -delete_address_space(vm_address_space *aspace) +delete_address_space(vm_address_space *addressSpace) { - TRACE(("delete_address_space: called on aspace 0x%lx\n", aspace->id)); + TRACE(("delete_address_space: called on aspace 0x%lx\n", addressSpace->id)); - if (aspace == kernel_aspace) + if (addressSpace == kernel_aspace) panic("tried to delete the kernel aspace!\n"); // put this aspace in the deletion state // this guarantees that no one else will add regions to the list - acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0); + acquire_sem_etc(addressSpace->sem, WRITE_COUNT, 0, 0); - aspace->state = VM_ASPACE_STATE_DELETION; + addressSpace->state = VM_ASPACE_STATE_DELETION; - (*aspace->translation_map.ops->destroy)(&aspace->translation_map); + (*addressSpace->translation_map.ops->destroy)(&addressSpace->translation_map); - free(aspace->name); - delete_sem(aspace->virtual_map.sem); - free(aspace); + delete_sem(addressSpace->sem); + free(addressSpace); } @@ -191,7 +179,7 @@ delete_address_space(vm_address_space *aspace) vm_address_space * -vm_get_aspace_by_id(aspace_id aid) +vm_get_address_space_by_id(team_id aid) { vm_address_space *aspace; @@ -206,44 +194,49 @@ vm_get_aspace_by_id(aspace_id aid) vm_address_space * -vm_get_kernel_aspace(void) +vm_get_kernel_address_space(void) { /* we can treat this one a little differently since it can't be deleted */ - acquire_sem_etc(aspace_hash_sem, READ_COUNT, 0, 0); atomic_add(&kernel_aspace->ref_count, 1); - release_sem_etc(aspace_hash_sem, READ_COUNT, 0); return kernel_aspace; } -aspace_id -vm_get_kernel_aspace_id(void) +vm_address_space * +vm_kernel_address_space(void) +{ + return kernel_aspace; +} + + +team_id +vm_kernel_address_space_id(void) { return kernel_aspace->id; } vm_address_space * -vm_get_current_user_aspace(void) +vm_get_current_user_address_space(void) { - return vm_get_aspace_by_id(vm_get_current_user_aspace_id()); + return vm_get_address_space_by_id(vm_current_user_address_space_id()); } -aspace_id -vm_get_current_user_aspace_id(void) +team_id +vm_current_user_address_space_id(void) { struct thread *thread = thread_get_current_thread(); - if (thread != NULL && thread->team->aspace != NULL) - return thread->team->aspace->id; + if (thread != NULL && thread->team->address_space != NULL) + return thread->team->id; return B_ERROR; } void -vm_put_aspace(vm_address_space *aspace) +vm_put_address_space(vm_address_space *aspace) { bool remove = false; @@ -268,69 +261,69 @@ vm_put_aspace(vm_address_space *aspace) */ void -vm_delete_aspace(vm_address_space *aspace) +vm_delete_address_space(vm_address_space *addressSpace) { - acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0); - aspace->state = VM_ASPACE_STATE_DELETION; - release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0); + acquire_sem_etc(addressSpace->sem, WRITE_COUNT, 0, 0); + addressSpace->state = VM_ASPACE_STATE_DELETION; + release_sem_etc(addressSpace->sem, WRITE_COUNT, 0); - vm_delete_areas(aspace); - vm_put_aspace(aspace); + vm_delete_areas(addressSpace); + vm_put_address_space(addressSpace); } status_t -vm_create_aspace(const char *name, team_id id, addr_t base, addr_t size, bool kernel, vm_address_space **_aspace) +vm_create_address_space(team_id id, addr_t base, addr_t size, + bool kernel, vm_address_space **_addressSpace) { - vm_address_space *aspace; + vm_address_space *addressSpace; status_t status; - aspace = (vm_address_space *)malloc(sizeof(vm_address_space)); - if (aspace == NULL) + addressSpace = (vm_address_space *)malloc(sizeof(vm_address_space)); + if (addressSpace == NULL) return B_NO_MEMORY; - TRACE(("vm_create_aspace: %s: %lx bytes starting at 0x%lx => %p\n", name, size, base, aspace)); + TRACE(("vm_create_aspace: %s: %lx bytes starting at 0x%lx => %p\n", + name, size, base, addressSpace)); - aspace->name = (char *)malloc(strlen(name) + 1); - if (aspace->name == NULL ) { - free(aspace); - return B_NO_MEMORY; + addressSpace->base = base; + addressSpace->size = size; + addressSpace->areas = NULL; + addressSpace->area_hint = NULL; + addressSpace->change_count = 0; + if (!kernel) { + // the kernel address space will create its semaphore later + addressSpace->sem = create_sem(WRITE_COUNT, "address space"); + if (addressSpace->sem < B_OK) { + status_t status = addressSpace->sem; + free(addressSpace); + return status; + } } - strcpy(aspace->name, name); - aspace->id = id; - aspace->ref_count = 1; - aspace->state = VM_ASPACE_STATE_NORMAL; - aspace->fault_count = 0; - aspace->scan_va = base; - aspace->working_set_size = kernel ? DEFAULT_KERNEL_WORKING_SET : DEFAULT_WORKING_SET; - aspace->max_working_set = DEFAULT_MAX_WORKING_SET; - aspace->min_working_set = DEFAULT_MIN_WORKING_SET; - aspace->last_working_set_adjust = system_time(); + addressSpace->id = id; + addressSpace->ref_count = 1; + addressSpace->state = VM_ASPACE_STATE_NORMAL; + addressSpace->fault_count = 0; + addressSpace->scan_va = base; + addressSpace->working_set_size = kernel ? DEFAULT_KERNEL_WORKING_SET : DEFAULT_WORKING_SET; + addressSpace->max_working_set = DEFAULT_MAX_WORKING_SET; + addressSpace->min_working_set = DEFAULT_MIN_WORKING_SET; + addressSpace->last_working_set_adjust = system_time(); // initialize the corresponding translation map - status = arch_vm_translation_map_init_map(&aspace->translation_map, kernel); + status = arch_vm_translation_map_init_map(&addressSpace->translation_map, kernel); if (status < B_OK) { - free(aspace->name); - free(aspace); + free(addressSpace); return status; } - // initialize the virtual map - aspace->virtual_map.base = base; - aspace->virtual_map.size = size; - aspace->virtual_map.areas = NULL; - aspace->virtual_map.area_hint = NULL; - aspace->virtual_map.change_count = 0; - aspace->virtual_map.sem = create_sem(WRITE_COUNT, "aspacelock"); - aspace->virtual_map.aspace = aspace; - // add the aspace to the global hash table acquire_sem_etc(aspace_hash_sem, WRITE_COUNT, 0, 0); - hash_insert(aspace_table, aspace); + hash_insert(aspace_table, addressSpace); release_sem_etc(aspace_hash_sem, WRITE_COUNT, 0); - *_aspace = aspace; + *_addressSpace = addressSpace; return B_OK; } @@ -358,7 +351,7 @@ vm_aspace_walk_next(struct hash_iterator *i) status_t -vm_aspace_init(void) +vm_address_space_init(void) { aspace_hash_sem = -1; @@ -374,7 +367,8 @@ vm_aspace_init(void) kernel_aspace = NULL; // create the initial kernel address space - if (vm_create_aspace("kernel_land", 1, KERNEL_BASE, KERNEL_SIZE, true, &kernel_aspace) != B_OK) + if (vm_create_address_space(1, KERNEL_BASE, KERNEL_SIZE, + true, &kernel_aspace) != B_OK) panic("vm_init: error creating kernel address space!\n"); add_debugger_command("aspaces", &dump_aspace_list, "Dump a list of all address spaces"); @@ -385,13 +379,13 @@ vm_aspace_init(void) status_t -vm_aspace_init_post_sem(void) +vm_address_space_init_post_sem(void) { status_t status = arch_vm_translation_map_init_kernel_map_post_sem(&kernel_aspace->translation_map); if (status < B_OK) return status; - status = kernel_aspace->virtual_map.sem = create_sem(WRITE_COUNT, "kernel_aspacelock"); + status = kernel_aspace->sem = create_sem(WRITE_COUNT, "kernel_aspacelock"); if (status < B_OK) return status; diff --git a/src/system/kernel/vm/vm_daemons.c b/src/system/kernel/vm/vm_daemons.c index cbacc35f84..1c6069c747 100644 --- a/src/system/kernel/vm/vm_daemons.c +++ b/src/system/kernel/vm/vm_daemons.c @@ -37,17 +37,17 @@ scan_pages(vm_address_space *aspace, addr_t free_target) // dprintf("scan_pages called on aspace 0x%x, id 0x%x, free_target %d\n", aspace, aspace->id, free_target); - acquire_sem_etc(aspace->virtual_map.sem, READ_COUNT, 0, 0); + acquire_sem_etc(aspace->sem, READ_COUNT, 0, 0); - firstArea = aspace->virtual_map.areas; + firstArea = aspace->areas; while (firstArea && (firstArea->base + (firstArea->size - 1)) < aspace->scan_va) - firstArea = firstArea->aspace_next; + firstArea = firstArea->address_space_next; if (!firstArea) - firstArea = aspace->virtual_map.areas; + firstArea = aspace->areas; if (!firstArea) { - release_sem_etc(aspace->virtual_map.sem, READ_COUNT, 0); + release_sem_etc(aspace->sem, READ_COUNT, 0); return; } @@ -55,7 +55,7 @@ scan_pages(vm_address_space *aspace, addr_t free_target) for (;;) { // ignore reserved ranges while (area != NULL && area->id == RESERVED_AREA_ID) - area = area->aspace_next; + area = area->address_space_next; if (area == NULL) break; @@ -120,7 +120,7 @@ scan_pages(vm_address_space *aspace, addr_t free_target) } mutex_unlock(&area->cache_ref->lock); // move to the next area, wrapping around and stopping if we get back to the first area - area = area->aspace_next ? area->aspace_next : aspace->virtual_map.areas; + area = area->address_space_next ? area->address_space_next : aspace->areas; if (area == firstArea) break; @@ -128,8 +128,8 @@ scan_pages(vm_address_space *aspace, addr_t free_target) break; } - aspace->scan_va = area ? (firstArea->base + firstArea->size) : aspace->virtual_map.base; - release_sem_etc(aspace->virtual_map.sem, READ_COUNT, 0); + aspace->scan_va = area ? (firstArea->base + firstArea->size) : aspace->base; + release_sem_etc(aspace->sem, READ_COUNT, 0); // dprintf("exiting scan_pages\n"); } @@ -199,7 +199,7 @@ page_daemon(void *unused) // otherwise the iterator becomes out of date. old_aspace = aspace; aspace = vm_aspace_walk_next(&i); - vm_put_aspace(old_aspace); + vm_put_address_space(old_aspace); } } } diff --git a/src/system/kernel/vm/vm_page.c b/src/system/kernel/vm/vm_page.c index 0223471b71..795d1d9c0a 100644 --- a/src/system/kernel/vm/vm_page.c +++ b/src/system/kernel/vm/vm_page.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -191,7 +191,7 @@ vm_page_write_modified(vm_cache *cache) for (area = page->cache->ref->areas; area; area = area->cache_next) { if (page->offset >= area->cache_offset && page->offset < area->cache_offset + area->size) { - vm_translation_map *map = &area->aspace->translation_map; + vm_translation_map *map = &area->address_space->translation_map; map->ops->lock(map); if (!gotPage) { diff --git a/src/system/kernel/vm/vm_tests.c b/src/system/kernel/vm/vm_tests.c index ed63434c30..bc970dbedc 100644 --- a/src/system/kernel/vm/vm_tests.c +++ b/src/system/kernel/vm/vm_tests.c @@ -1,10 +1,10 @@ /* -** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the Haiku License. -** -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ + * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ #include #include @@ -28,7 +28,7 @@ vm_test(void) area_id region; addr_t region_addr; - region = vm_create_anonymous_area(vm_get_kernel_aspace_id(), "test_region", (void **)®ion_addr, + region = vm_create_anonymous_area(vm_kernel_address_space_id(), "test_region", (void **)®ion_addr, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE * 16, B_NO_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (region < 0) panic("vm_test 1: failed to create test region\n"); @@ -37,7 +37,7 @@ vm_test(void) memset((void *)region_addr, 0, B_PAGE_SIZE * 16); dprintf("memsetted the region\n"); - if (vm_delete_area(vm_get_kernel_aspace_id(), region) < 0) + if (vm_delete_area(vm_kernel_address_space_id(), region) < 0) panic("vm_test 1: error deleting test region\n"); dprintf("deleted the region\n"); } @@ -50,7 +50,7 @@ vm_test(void) char *ptr; int i; - region = vm_map_physical_memory(vm_get_kernel_aspace_id(), "test_physical_region", (void **)&ptr, + region = vm_map_physical_memory(vm_kernel_address_space_id(), "test_physical_region", (void **)&ptr, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE * 16, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0xb8000); if (region < 0) panic("vm_test 2: failed to create test region\n"); @@ -63,7 +63,7 @@ vm_test(void) for(i=0; i<64; i++) { ptr[i] = 'a'; } - if (vm_delete_area(vm_get_kernel_aspace_id(), region) < 0) + if (vm_delete_area(vm_kernel_address_space_id(), region) < 0) panic("vm_test 2: error deleting test region\n"); dprintf("deleted the region\n"); } @@ -74,12 +74,12 @@ vm_test(void) addr_t va, pa; addr_t va2; - vm_get_page_mapping(vm_get_kernel_aspace_id(), 0x80000000, &pa); + vm_get_page_mapping(vm_kernel_address_space_id(), 0x80000000, &pa); vm_get_physical_page(pa, &va, PHYSICAL_PAGE_CAN_WAIT); dprintf("pa 0x%lx va 0x%lx\n", pa, va); dprintf("%d\n", memcmp((void *)0x80000000, (void *)va, B_PAGE_SIZE)); - vm_get_page_mapping(vm_get_kernel_aspace_id(), 0x80001000, &pa); + vm_get_page_mapping(vm_kernel_address_space_id(), 0x80001000, &pa); vm_get_physical_page(pa, &va2, PHYSICAL_PAGE_CAN_WAIT); dprintf("pa 0x%lx va 0x%lx\n", pa, va2); dprintf("%d\n", memcmp((void *)0x80001000, (void *)va2, B_PAGE_SIZE)); @@ -87,7 +87,7 @@ vm_test(void) vm_put_physical_page(va); vm_put_physical_page(va2); - vm_get_page_mapping(vm_get_kernel_aspace_id(), 0x80000000, &pa); + vm_get_page_mapping(vm_kernel_address_space_id(), 0x80000000, &pa); vm_get_physical_page(pa, &va, PHYSICAL_PAGE_CAN_WAIT); dprintf("pa 0x%lx va 0x%lx\n", pa, va); dprintf("%d\n", memcmp((void *)0x80000000, (void *)va, B_PAGE_SIZE)); @@ -108,7 +108,7 @@ vm_test(void) panic("vm_test 4: error finding region 'vid_mem'\n"); dprintf("vid_mem region = 0x%lx\n", region); - region2 = vm_clone_area(vm_get_kernel_aspace_id(), "vid_mem2", + region2 = vm_clone_area(vm_kernel_address_space_id(), "vid_mem2", &ptr, B_ANY_KERNEL_ADDRESS, region, REGION_NO_PRIVATE_MAP, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (region2 < 0) panic("vm_test 4: error cloning region 'vid_mem'\n"); @@ -120,7 +120,7 @@ vm_test(void) panic("vm_test 4: regions are not identical\n"); else dprintf("vm_test 4: comparison ok\n"); - if (vm_delete_area(vm_get_kernel_aspace_id(), region2) < 0) + if (vm_delete_area(vm_kernel_address_space_id(), region2) < 0) panic("vm_test 4: error deleting cloned region\n"); } #endif @@ -137,7 +137,7 @@ vm_test(void) panic("vm_test 5: error finding region 'vid_mem'\n"); dprintf("vid_mem region = 0x%lx\n", region); - region2 = vm_clone_area(vm_get_kernel_aspace_id(), "vid_mem3", + region2 = vm_clone_area(vm_kernel_address_space_id(), "vid_mem3", &ptr, B_ANY_KERNEL_ADDRESS, region, REGION_NO_PRIVATE_MAP, B_KERNEL_READ_AREA); if (region2 < 0) panic("vm_test 5: error cloning region 'vid_mem'\n"); @@ -150,7 +150,7 @@ vm_test(void) else dprintf("vm_test 5: comparison ok\n"); - if (vm_delete_area(vm_get_kernel_aspace_id(), region2) < 0) + if (vm_delete_area(vm_kernel_address_space_id(), region2) < 0) panic("vm_test 5: error deleting cloned region\n"); } #endif @@ -162,7 +162,7 @@ vm_test(void) void *ptr; int rc; - region = vm_create_anonymous_area(vm_get_kernel_aspace_id(), "test_region", ®ion_addr, + region = vm_create_anonymous_area(vm_kernel_address_space_id(), "test_region", ®ion_addr, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE * 16, B_NO_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (region < 0) panic("vm_test 6: error creating test region\n"); @@ -172,7 +172,7 @@ vm_test(void) dprintf("memsetted the region\n"); - region2 = vm_clone_area(vm_get_kernel_aspace_id(), "test_region2", + region2 = vm_clone_area(vm_kernel_address_space_id(), "test_region2", &ptr, B_ANY_KERNEL_ADDRESS, region, REGION_NO_PRIVATE_MAP, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if(region2 < 0) panic("vm_test 6: error cloning test region\n"); @@ -184,10 +184,10 @@ vm_test(void) else dprintf("vm_test 6: comparison ok\n"); - if(vm_delete_area(vm_get_kernel_aspace_id(), region) < 0) + if(vm_delete_area(vm_kernel_address_space_id(), region) < 0) panic("vm_test 6: error deleting test region\n"); - if(vm_delete_area(vm_get_kernel_aspace_id(), region2) < 0) + if(vm_delete_area(vm_kernel_address_space_id(), region2) < 0) panic("vm_test 6: error deleting cloned region\n"); } #endif @@ -201,18 +201,18 @@ vm_test(void) fd = _kern_open("/boot/beos/system/kernel_" OBOS_ARCH, 0); - rid = vm_map_file(vm_get_kernel_aspace_id(), "mmap_test", &ptr, B_ANY_KERNEL_ADDRESS, + rid = vm_map_file(vm_kernel_address_space_id(), "mmap_test", &ptr, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, REGION_NO_PRIVATE_MAP, "/boot/kernel", 0); - rid2 = vm_map_file(vm_get_kernel_aspace_id(), "mmap_test2", &ptr2, B_ANY_KERNEL_ADDRESS, + rid2 = vm_map_file(vm_kernel_address_space_id(), "mmap_test2", &ptr2, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, REGION_NO_PRIVATE_MAP, "/boot/kernel", 0); dprintf("diff %d\n", memcmp(ptr, ptr2, B_PAGE_SIZE)); dprintf("removing regions\n"); - vm_delete_area(vm_get_kernel_aspace_id(), rid); - vm_delete_area(vm_get_kernel_aspace_id(), rid2); + vm_delete_area(vm_kernel_address_space_id(), rid); + vm_delete_area(vm_kernel_address_space_id(), rid2); dprintf("regions deleted\n"); @@ -231,7 +231,7 @@ vm_test(void) dprintf("vm_test 8: creating test region...\n"); - region = vm_create_anonymous_area(vm_get_kernel_aspace_id(), "test_region", ®ion_addr, + region = vm_create_anonymous_area(vm_kernel_address_space_id(), "test_region", ®ion_addr, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE * 16, B_NO_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if(region < 0) panic("vm_test 8: error creating test region\n"); @@ -243,7 +243,7 @@ vm_test(void) dprintf("vm_test 8: cloning test region with PRIVATE_MAP\n"); - region2 = vm_clone_area(vm_get_kernel_aspace_id(), "test_region2", + region2 = vm_clone_area(vm_kernel_address_space_id(), "test_region2", &ptr, B_ANY_KERNEL_ADDRESS, region, REGION_PRIVATE_MAP, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if(region2 < 0) panic("vm_test 8: error cloning test region\n"); @@ -296,10 +296,10 @@ vm_test(void) else panic("vm_test 8: comparison shows not private mapping\n"); - if(vm_delete_area(vm_get_kernel_aspace_id(), region) < 0) + if(vm_delete_area(vm_kernel_address_space_id(), region) < 0) panic("vm_test 8: error deleting test region\n"); - if(vm_delete_area(vm_get_kernel_aspace_id(), region2) < 0) + if(vm_delete_area(vm_kernel_address_space_id(), region2) < 0) panic("vm_test 8: error deleting cloned region\n"); } #endif @@ -312,10 +312,10 @@ vm_test(void) dprintf("vm_test 9: mapping /boot/kernel twice\n"); - rid = vm_map_file(vm_get_kernel_aspace_id(), "mmap_test", &ptr, B_ANY_KERNEL_ADDRESS, + rid = vm_map_file(vm_kernel_address_space_id(), "mmap_test", &ptr, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE*4, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, REGION_NO_PRIVATE_MAP, "/boot/kernel", 0); - rid2 = vm_map_file(vm_get_kernel_aspace_id(), "mmap_test2", &ptr2, B_ANY_KERNEL_ADDRESS, + rid2 = vm_map_file(vm_kernel_address_space_id(), "mmap_test2", &ptr2, B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE*4, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, REGION_PRIVATE_MAP, "/boot/kernel", 0); err = memcmp(ptr, ptr2, B_PAGE_SIZE); @@ -348,8 +348,8 @@ vm_test(void) dprintf("vm_test 9: removing regions\n"); - vm_delete_area(vm_get_kernel_aspace_id(), rid); - vm_delete_area(vm_get_kernel_aspace_id(), rid2); + vm_delete_area(vm_kernel_address_space_id(), rid); + vm_delete_area(vm_kernel_address_space_id(), rid2); dprintf("vm_test 9: regions deleted\n"); @@ -371,7 +371,7 @@ vm_test(void) ta[2048] = 0xabcd; ta[3072] = 0xefef; - b = vm_copy_area(vm_get_kernel_aspace_id(), "copy of source", &address, B_ANY_KERNEL_ADDRESS, + b = vm_copy_area(vm_kernel_address_space_id(), "copy of source", &address, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, a); tb = (uint32 *)address; if (tb[0] != 0x1234 || tb[1024] != 0x5678 || tb[2048] != 0xabcd || tb[3072] != 0xefef) @@ -387,8 +387,8 @@ vm_test(void) dprintf("vm_test 10: remove areas\n"); - vm_delete_area(vm_get_kernel_aspace_id(), a); - vm_delete_area(vm_get_kernel_aspace_id(), b); + vm_delete_area(vm_kernel_address_space_id(), a); + vm_delete_area(vm_kernel_address_space_id(), b); } dprintf("vm_test 10: passed\n"); #endif @@ -417,7 +417,7 @@ vm_test(void) dprintf("vm_test 11: remove areas\n"); - vm_delete_area(vm_get_kernel_aspace_id(), a); + vm_delete_area(vm_kernel_address_space_id(), a); } dprintf("vm_test 11: passed\n"); #endif