diff --git a/headers/os/drivers/KernelExport.h b/headers/os/drivers/KernelExport.h index 3a88928a65..8bbf0755d3 100644 --- a/headers/os/drivers/KernelExport.h +++ b/headers/os/drivers/KernelExport.h @@ -144,8 +144,12 @@ extern thread_id spawn_kernel_thread(thread_func function, extern int send_signal_etc(pid_t thread, uint signal, uint32 flags); /* virtual memory */ -extern long lock_memory(void *buffer, ulong numBytes, ulong flags); -extern long unlock_memory(void *buffer, ulong numBytes, ulong flags); +extern status_t lock_memory_etc(team_id team, void *buffer, size_t numBytes, + uint32 flags); +extern status_t lock_memory(void *buffer, size_t numBytes, uint32 flags); +extern status_t unlock_memory_etc(team_id team, void *address, + size_t numBytes, uint32 flags); +extern status_t unlock_memory(void *buffer, size_t numBytes, uint32 flags); extern long get_memory_map(const void *buffer, ulong size, physical_entry *table, long numEntries); extern area_id map_physical_memory(const char *areaName, @@ -168,7 +172,7 @@ extern uint64 parse_expression(const char *string); extern int add_debugger_command(char *name, debugger_command_hook hook, char *help); extern int remove_debugger_command(char *name, - debugger_command_hook hook); + debugger_command_hook hook); /* Miscellaneous */ extern void spin(bigtime_t microseconds); diff --git a/headers/private/kernel/vm.h b/headers/private/kernel/vm.h index 4c3067a4c2..ac27518635 100644 --- a/headers/private/kernel/vm.h +++ b/headers/private/kernel/vm.h @@ -46,9 +46,8 @@ void permit_page_faults(void); void forbid_page_faults(void); // private kernel only extension (should be moved somewhere else): -area_id create_area_etc(struct team *team, const char *name, void **address, +area_id create_area_etc(team_id 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(team_id team, void *address, addr_t size); status_t vm_reserve_address_range(team_id team, void **_address, diff --git a/headers/private/kernel/vm_address_space.h b/headers/private/kernel/vm_address_space.h index 5b3c6456bd..81c3021840 100644 --- a/headers/private/kernel/vm_address_space.h +++ b/headers/private/kernel/vm_address_space.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -32,7 +32,7 @@ struct vm_address_space *vm_kernel_address_space(void); team_id vm_kernel_address_space_id(void); struct vm_address_space *vm_get_current_user_address_space(void); team_id vm_current_user_address_space_id(void); -struct vm_address_space *vm_get_address_space_by_id(team_id aid); +struct vm_address_space *vm_get_address_space(team_id team); void vm_put_address_space(struct vm_address_space *aspace); #define vm_swap_address_space(aspace) arch_vm_aspace_swap(aspace) diff --git a/src/system/kernel/arch/x86/vm86.cpp b/src/system/kernel/arch/x86/vm86.cpp index 5e41a9bba6..4af80813db 100644 --- a/src/system/kernel/arch/x86/vm86.cpp +++ b/src/system/kernel/arch/x86/vm86.cpp @@ -547,9 +547,8 @@ vm86_prepare(struct vm86_state *state, unsigned int ramSize) ramSize = VM86_MIN_RAM_SIZE; void *address = (void *)0; - state->ram_area = create_area_etc(team, "dos", &address, B_EXACT_ADDRESS, - ramSize, B_NO_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA - | B_READ_AREA | B_WRITE_AREA); + state->ram_area = create_area_etc(team->id, "dos", &address, + B_EXACT_ADDRESS, ramSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (state->ram_area < B_OK) { ret = state->ram_area; TRACE("Could not create RAM area\n"); @@ -566,7 +565,7 @@ vm86_prepare(struct vm86_state *state, unsigned int ramSize) goto error; } ret = user_memcpy((void *)0, address, 0x502); - *((uint32 *)0) = 0xDEADBEEF; + *((uint32 *)0) = 0xdeadbeef; delete_area(vectors); if (ret != B_OK) goto error; @@ -586,9 +585,9 @@ vm86_prepare(struct vm86_state *state, unsigned int ramSize) error: if (state->bios_area > B_OK) - delete_area_etc(team, state->bios_area); + vm_delete_area(team->id, state->bios_area, true); if (state->ram_area > B_OK) - delete_area_etc(team, state->ram_area); + vm_delete_area(team->id, state->ram_area, true); return ret; } @@ -601,9 +600,9 @@ vm86_cleanup(struct vm86_state *state) struct team *team = thread_get_current_thread()->team; if (state->bios_area > B_OK) - delete_area_etc(team, state->bios_area); + vm_delete_area(team->id, state->bios_area, true); if (state->ram_area > B_OK) - delete_area_etc(team, state->ram_area); + vm_delete_area(team->id, state->ram_area, true); } diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index 2c1834a9d9..a8fd84d5ff 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -1457,8 +1457,9 @@ elf_load_user_image(const char *path, struct team *team, int flags, addr_t *entr snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i); regionAddress += fileUpperBound; - id = create_area_etc(team, regionName, (void **)®ionAddress, - B_EXACT_ADDRESS, bss_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + id = create_area_etc(team->id, 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)); status = B_NOT_AN_EXECUTABLE; diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 3f7de5f00a..e19afe3657 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -160,7 +160,7 @@ class ExecTeam : public AbstractTraceEntry { for (int32 i = 0; !out.IsFull() && i < fArgCount; i++) { out.Print(" \"%s\"", args); args += strlen(args) + 1; - } + } } private: @@ -812,7 +812,7 @@ create_team_user_data(struct team* team) { void* address = (void*)KERNEL_USER_DATA_BASE; size_t size = 4 * B_PAGE_SIZE; - team->user_data_area = create_area_etc(team, "user area", &address, + team->user_data_area = create_area_etc(team->id, "user area", &address, B_BASE_ADDRESS, size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA); if (team->user_data_area < 0) return team->user_data_area; @@ -830,7 +830,7 @@ static void delete_team_user_data(struct team* team) { if (team->user_data_area >= 0) { - delete_area_etc(team, team->user_data_area); + vm_delete_area(team->id, team->user_data_area, true); team->user_data = 0; team->used_user_data = 0; team->user_data_size = 0; @@ -989,8 +989,9 @@ team_create_thread_start(void *args) // the exact location at the end of the user stack area sprintf(ustack_name, "%s_main_stack", team->name); - t->user_stack_area = create_area_etc(team, ustack_name, (void **)&t->user_stack_base, - B_EXACT_ADDRESS, sizeLeft, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA); + t->user_stack_area = create_area_etc(team->id, ustack_name, + (void **)&t->user_stack_base, B_EXACT_ADDRESS, sizeLeft, B_NO_LOCK, + B_READ_AREA | B_WRITE_AREA | B_STACK_AREA); if (t->user_stack_area < 0) { dprintf("team_create_thread_start: could not create default user stack region\n"); @@ -1050,7 +1051,7 @@ team_create_thread_start(void *args) runtimeLoaderPath.LockBuffer(), runtimeLoaderPath.BufferSize()); if (err < B_OK) { TRACE(("team_create_thread_start: find_directory() failed: %s\n", - strerror(err))); + strerror(err))); return err; } runtimeLoaderPath.UnlockBuffer(); @@ -1064,7 +1065,7 @@ team_create_thread_start(void *args) // Luckily, we don't have to clean up the mess we created - that's // done for us by the normal team deletion process TRACE(("team_create_thread_start: elf_load_user_image() failed: " - "%s\n", strerror(err))); + "%s\n", strerror(err))); return err; } @@ -1210,7 +1211,7 @@ load_image_etc(char**& _flatArgs, size_t flatArgsSize, int32 argCount, if (loadingInfo.result < B_OK) return loadingInfo.result; - } + } // notify the debugger user_debug_team_created(team->id); @@ -1849,11 +1850,11 @@ fill_team_info(struct team *team, team_info *info, size_t size) info->team = team->id; info->thread_count = team->num_threads; info->image_count = count_images(team); - //info->area_count = + //info->area_count = info->debugger_nub_thread = team->debug_info.nub_thread; info->debugger_nub_port = team->debug_info.nub_port; - //info->uid = - //info->gid = + //info->uid = + //info->gid = strlcpy(info->args, team->args, sizeof(info->args)); info->argc = 1; @@ -2187,7 +2188,7 @@ team_remove_team(struct team *team) session->controlling_tty = -1; - // send SIGHUP to the foreground + // send SIGHUP to the foreground if (session->foreground_group >= 0) { send_signal_etc(-session->foreground_group, SIGHUP, SIGNAL_FLAG_TEAMS_LOCKED); @@ -2206,7 +2207,7 @@ team_remove_team(struct team *team) send_signal_etc(-childGroup->id, SIGCONT, SIGNAL_FLAG_TEAMS_LOCKED); } - + child = child->siblings_next; } } else { @@ -2216,7 +2217,7 @@ team_remove_team(struct team *team) process_group* childGroup = child->group; if (!childGroup->orphaned) update_orphaned_process_group(childGroup, team->id); - + child = child->siblings_next; } @@ -2509,8 +2510,8 @@ start_watching_team(team_id teamID, void (*hook)(team_id, void *), void *data) return B_OK; } - - + + status_t stop_watching_team(team_id teamID, void (*hook)(team_id, void *), void *data) { @@ -3304,7 +3305,7 @@ _user_get_team_info(team_id id, team_info *userInfo) team_info info; if (!IS_USER_ADDRESS(userInfo)) - return B_BAD_ADDRESS; + return B_BAD_ADDRESS; status = _get_team_info(id, &info, sizeof(team_info)); if (status == B_OK) { diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 67e95a350c..28beeb98cd 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -502,7 +502,7 @@ create_thread(thread_creation_attributes& attributes, bool kernel) snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%ld_stack", attributes.name, thread->id); - thread->user_stack_area = create_area_etc(team, stack_name, + thread->user_stack_area = create_area_etc(team->id, stack_name, (void **)&thread->user_stack_base, B_BASE_ADDRESS, thread->user_stack_size + TLS_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA); @@ -1003,7 +1003,7 @@ state_to_text(struct thread *thread, int32 state) switch (thread->wait.type) { case THREAD_BLOCK_TYPE_SNOOZE: return "zzz"; - + case THREAD_BLOCK_TYPE_SEMAPHORE: { sem_id sem = (sem_id)(addr_t)thread->wait.object; @@ -1314,7 +1314,7 @@ thread_exit(void) 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); + vm_delete_area(team->id, area, true); } struct job_control_entry *death = NULL; @@ -2550,7 +2550,7 @@ getrlimit(int resource, struct rlimit * rlp) return -1; } - return 0; + return 0; } @@ -2563,7 +2563,7 @@ setrlimit(int resource, const struct rlimit * rlp) return -1; } - return 0; + return 0; } diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index c15e96ff33..4a5202e1ca 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -272,7 +272,7 @@ AddressSpaceReadLocker::Unset() status_t AddressSpaceReadLocker::SetTo(team_id team) { - fSpace = vm_get_address_space_by_id(team); + fSpace = vm_get_address_space(team); if (fSpace == NULL) return B_BAD_TEAM_ID; @@ -365,7 +365,7 @@ AddressSpaceWriteLocker::Unset() status_t AddressSpaceWriteLocker::SetTo(team_id team) { - fSpace = vm_get_address_space_by_id(team); + fSpace = vm_get_address_space(team); if (fSpace == NULL) return B_BAD_TEAM_ID; @@ -557,7 +557,7 @@ inline status_t MultiAddressSpaceLocker::AddTeam(team_id team, bool writeLock, vm_address_space** _space) { - return _AddAddressSpace(vm_get_address_space_by_id(team), writeLock, + return _AddAddressSpace(vm_get_address_space(team), writeLock, _space); } @@ -1327,7 +1327,7 @@ unmap_address_range(vm_address_space *addressSpace, addr_t address, addr_t size, area = addressSpace->areas; while (area != NULL) { vm_area* nextArea = area->address_space_next; - + if (area->id != RESERVED_AREA_ID) { addr_t areaLast = area->base + (area->size - 1); if (area->base < lastAddress && address < areaLast) { @@ -1335,7 +1335,7 @@ unmap_address_range(vm_address_space *addressSpace, addr_t address, addr_t size, return B_NOT_ALLOWED; } } - + area = nextArea; } } @@ -2599,7 +2599,7 @@ vm_set_area_protection(team_id team, area_id areaID, uint32 newProtection, status_t vm_get_page_mapping(team_id team, addr_t vaddr, addr_t *paddr) { - vm_address_space *addressSpace = vm_get_address_space_by_id(team); + vm_address_space *addressSpace = vm_get_address_space(team); if (addressSpace == NULL) return B_BAD_TEAM_ID; @@ -5021,8 +5021,8 @@ user_memset(void *s, char c, size_t count) } -long -lock_memory(void *address, ulong numBytes, ulong flags) +status_t +lock_memory_etc(team_id team, void *address, size_t numBytes, uint32 flags) { vm_address_space *addressSpace = NULL; struct vm_translation_map *map; @@ -5032,9 +5032,12 @@ lock_memory(void *address, ulong numBytes, ulong flags) bool isUser = IS_USER_ADDRESS(address); bool needsLocking = true; - if (isUser) - addressSpace = vm_get_current_user_address_space(); - else + if (isUser) { + if (team == B_CURRENT_TEAM) + addressSpace = vm_get_current_user_address_space(); + else + addressSpace = vm_get_address_space(team); + } else addressSpace = vm_get_kernel_address_space(); if (addressSpace == NULL) return B_ERROR; @@ -5107,8 +5110,15 @@ out: } -long -unlock_memory(void *address, ulong numBytes, ulong flags) +status_t +lock_memory(void *address, size_t numBytes, uint32 flags) +{ + return lock_memory_etc(B_CURRENT_TEAM, address, numBytes, flags); +} + + +status_t +unlock_memory_etc(team_id team, void *address, size_t numBytes, uint32 flags) { vm_address_space *addressSpace = NULL; struct vm_translation_map *map; @@ -5117,9 +5127,12 @@ unlock_memory(void *address, ulong numBytes, ulong flags) addr_t base = ROUNDOWN(unalignedBase, B_PAGE_SIZE); bool needsLocking = true; - if (IS_USER_ADDRESS(address)) - addressSpace = vm_get_current_user_address_space(); - else + if (IS_USER_ADDRESS(address)) { + if (team == B_CURRENT_TEAM) + addressSpace = vm_get_current_user_address_space(); + else + addressSpace = vm_get_address_space(team); + } else addressSpace = vm_get_kernel_address_space(); if (addressSpace == NULL) return B_ERROR; @@ -5162,10 +5175,16 @@ out: } -/** According to the BeBook, this function should always succeed. - * This is no longer the case. - */ +status_t +unlock_memory(void *address, size_t numBytes, uint32 flags) +{ + return unlock_memory_etc(B_CURRENT_TEAM, address, numBytes, flags); +} + +/*! According to the BeBook, this function should always succeed. + This is no longer the case. +*/ long get_memory_map(const void *address, ulong numBytes, physical_entry *table, long numEntries) @@ -5434,13 +5453,13 @@ clone_area(const char *name, void **_address, uint32 addressSpec, area_id -create_area_etc(struct team *team, const char *name, void **address, uint32 addressSpec, - uint32 size, uint32 lock, uint32 protection) +create_area_etc(team_id team, const char *name, void **address, + uint32 addressSpec, uint32 size, uint32 lock, uint32 protection) { fix_protection(&protection); - return vm_create_anonymous_area(team->id, (char *)name, address, - addressSpec, size, lock, protection, false, true); + return vm_create_anonymous_area(team, (char *)name, address, addressSpec, + size, lock, protection, false, true); } @@ -5455,13 +5474,6 @@ create_area(const char *name, void **_address, uint32 addressSpec, size_t size, } -status_t -delete_area_etc(struct team *team, area_id area) -{ - return vm_delete_area(team->id, area, true); -} - - status_t delete_area(area_id area) { @@ -5841,7 +5853,7 @@ _user_sync_memory(void *_address, addr_t size, int flags) address += rangeSize; size -= rangeSize; } - + // NOTE: If I understand it correctly the purpose of MS_INVALIDATE is to // synchronize multiple mappings of the same file. In our VM they never get // out of sync, though, so we don't have to do anything. diff --git a/src/system/kernel/vm/vm_address_space.cpp b/src/system/kernel/vm/vm_address_space.cpp index 984fa6db55..e44e3936c8 100644 --- a/src/system/kernel/vm/vm_address_space.cpp +++ b/src/system/kernel/vm/vm_address_space.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -166,7 +166,7 @@ delete_address_space(vm_address_space *addressSpace) vm_address_space * -vm_get_address_space_by_id(team_id id) +vm_get_address_space(team_id id) { vm_address_space *addressSpace; @@ -334,7 +334,7 @@ vm_address_space_init(void) // create the area and address space hash tables { vm_address_space *aspace; - sAddressSpaceTable = hash_init(ASPACE_HASH_TABLE_SIZE, + sAddressSpaceTable = hash_init(ASPACE_HASH_TABLE_SIZE, (addr_t)&aspace->hash_next - (addr_t)aspace, &aspace_compare, &aspace_hash); if (sAddressSpaceTable == NULL)