* Added [un]lock_memory_etc() versions that accept a team_id as first argument.

This allows drivers to lock the memory outside of the original team context.
* create_area_etc() got a struct team as first argument, but that should have
  been a team_id.
* Removed delete_area_etc() - there is already vm_delete_area() doing the same
  thing.
* Renamed vm_get_address_space_by_id() to vm_get_address_space(), as there is
  no other method of getting an address space.
* Removed erroneous white space.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26455 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-07-16 22:55:17 +00:00
parent cb9191556c
commit 736352dcf5
9 changed files with 89 additions and 73 deletions
+6 -2
View File
@@ -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); extern int send_signal_etc(pid_t thread, uint signal, uint32 flags);
/* virtual memory */ /* virtual memory */
extern long lock_memory(void *buffer, ulong numBytes, ulong flags); extern status_t lock_memory_etc(team_id team, void *buffer, size_t numBytes,
extern long unlock_memory(void *buffer, ulong numBytes, ulong flags); 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, extern long get_memory_map(const void *buffer, ulong size,
physical_entry *table, long numEntries); physical_entry *table, long numEntries);
extern area_id map_physical_memory(const char *areaName, extern area_id map_physical_memory(const char *areaName,
+1 -2
View File
@@ -46,9 +46,8 @@ void permit_page_faults(void);
void forbid_page_faults(void); void forbid_page_faults(void);
// private kernel only extension (should be moved somewhere else): // 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); 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_unreserve_address_range(team_id team, void *address, addr_t size);
status_t vm_reserve_address_range(team_id team, void **_address, status_t vm_reserve_address_range(team_id team, void **_address,
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2005, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * 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); team_id vm_kernel_address_space_id(void);
struct vm_address_space *vm_get_current_user_address_space(void); struct vm_address_space *vm_get_current_user_address_space(void);
team_id vm_current_user_address_space_id(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); void vm_put_address_space(struct vm_address_space *aspace);
#define vm_swap_address_space(aspace) arch_vm_aspace_swap(aspace) #define vm_swap_address_space(aspace) arch_vm_aspace_swap(aspace)
+7 -8
View File
@@ -547,9 +547,8 @@ vm86_prepare(struct vm86_state *state, unsigned int ramSize)
ramSize = VM86_MIN_RAM_SIZE; ramSize = VM86_MIN_RAM_SIZE;
void *address = (void *)0; void *address = (void *)0;
state->ram_area = create_area_etc(team, "dos", &address, B_EXACT_ADDRESS, state->ram_area = create_area_etc(team->id, "dos", &address,
ramSize, B_NO_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA B_EXACT_ADDRESS, ramSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
| B_READ_AREA | B_WRITE_AREA);
if (state->ram_area < B_OK) { if (state->ram_area < B_OK) {
ret = state->ram_area; ret = state->ram_area;
TRACE("Could not create RAM area\n"); TRACE("Could not create RAM area\n");
@@ -566,7 +565,7 @@ vm86_prepare(struct vm86_state *state, unsigned int ramSize)
goto error; goto error;
} }
ret = user_memcpy((void *)0, address, 0x502); ret = user_memcpy((void *)0, address, 0x502);
*((uint32 *)0) = 0xDEADBEEF; *((uint32 *)0) = 0xdeadbeef;
delete_area(vectors); delete_area(vectors);
if (ret != B_OK) if (ret != B_OK)
goto error; goto error;
@@ -586,9 +585,9 @@ vm86_prepare(struct vm86_state *state, unsigned int ramSize)
error: error:
if (state->bios_area > B_OK) 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) if (state->ram_area > B_OK)
delete_area_etc(team, state->ram_area); vm_delete_area(team->id, state->ram_area, true);
return ret; return ret;
} }
@@ -601,9 +600,9 @@ vm86_cleanup(struct vm86_state *state)
struct team *team = thread_get_current_thread()->team; struct team *team = thread_get_current_thread()->team;
if (state->bios_area > B_OK) 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) if (state->ram_area > B_OK)
delete_area_etc(team, state->ram_area); vm_delete_area(team->id, state->ram_area, true);
} }
+3 -2
View File
@@ -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); snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i);
regionAddress += fileUpperBound; regionAddress += fileUpperBound;
id = create_area_etc(team, regionName, (void **)&regionAddress, id = create_area_etc(team->id, regionName,
B_EXACT_ADDRESS, bss_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); (void **)&regionAddress, B_EXACT_ADDRESS, bss_size,
B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (id < B_OK) { if (id < B_OK) {
dprintf("error allocating bss area: %s!\n", strerror(id)); dprintf("error allocating bss area: %s!\n", strerror(id));
status = B_NOT_AN_EXECUTABLE; status = B_NOT_AN_EXECUTABLE;
+5 -4
View File
@@ -812,7 +812,7 @@ create_team_user_data(struct team* team)
{ {
void* address = (void*)KERNEL_USER_DATA_BASE; void* address = (void*)KERNEL_USER_DATA_BASE;
size_t size = 4 * B_PAGE_SIZE; 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); B_BASE_ADDRESS, size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA);
if (team->user_data_area < 0) if (team->user_data_area < 0)
return team->user_data_area; return team->user_data_area;
@@ -830,7 +830,7 @@ static void
delete_team_user_data(struct team* team) delete_team_user_data(struct team* team)
{ {
if (team->user_data_area >= 0) { 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->user_data = 0;
team->used_user_data = 0; team->used_user_data = 0;
team->user_data_size = 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 // the exact location at the end of the user stack area
sprintf(ustack_name, "%s_main_stack", team->name); sprintf(ustack_name, "%s_main_stack", team->name);
t->user_stack_area = create_area_etc(team, ustack_name, (void **)&t->user_stack_base, t->user_stack_area = create_area_etc(team->id, ustack_name,
B_EXACT_ADDRESS, sizeLeft, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA); (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) { if (t->user_stack_area < 0) {
dprintf("team_create_thread_start: could not create default user stack region\n"); dprintf("team_create_thread_start: could not create default user stack region\n");
+2 -2
View File
@@ -502,7 +502,7 @@ create_thread(thread_creation_attributes& attributes, bool kernel)
snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%ld_stack", snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%ld_stack",
attributes.name, thread->id); 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, (void **)&thread->user_stack_base, B_BASE_ADDRESS,
thread->user_stack_size + TLS_SIZE, B_NO_LOCK, thread->user_stack_size + TLS_SIZE, B_NO_LOCK,
B_READ_AREA | B_WRITE_AREA | B_STACK_AREA); B_READ_AREA | B_WRITE_AREA | B_STACK_AREA);
@@ -1314,7 +1314,7 @@ thread_exit(void)
if (team->address_space != NULL && thread->user_stack_area >= 0) { if (team->address_space != NULL && thread->user_stack_area >= 0) {
area_id area = thread->user_stack_area; area_id area = thread->user_stack_area;
thread->user_stack_area = -1; thread->user_stack_area = -1;
delete_area_etc(team, area); vm_delete_area(team->id, area, true);
} }
struct job_control_entry *death = NULL; struct job_control_entry *death = NULL;
+40 -28
View File
@@ -272,7 +272,7 @@ AddressSpaceReadLocker::Unset()
status_t status_t
AddressSpaceReadLocker::SetTo(team_id team) AddressSpaceReadLocker::SetTo(team_id team)
{ {
fSpace = vm_get_address_space_by_id(team); fSpace = vm_get_address_space(team);
if (fSpace == NULL) if (fSpace == NULL)
return B_BAD_TEAM_ID; return B_BAD_TEAM_ID;
@@ -365,7 +365,7 @@ AddressSpaceWriteLocker::Unset()
status_t status_t
AddressSpaceWriteLocker::SetTo(team_id team) AddressSpaceWriteLocker::SetTo(team_id team)
{ {
fSpace = vm_get_address_space_by_id(team); fSpace = vm_get_address_space(team);
if (fSpace == NULL) if (fSpace == NULL)
return B_BAD_TEAM_ID; return B_BAD_TEAM_ID;
@@ -557,7 +557,7 @@ inline status_t
MultiAddressSpaceLocker::AddTeam(team_id team, bool writeLock, MultiAddressSpaceLocker::AddTeam(team_id team, bool writeLock,
vm_address_space** _space) vm_address_space** _space)
{ {
return _AddAddressSpace(vm_get_address_space_by_id(team), writeLock, return _AddAddressSpace(vm_get_address_space(team), writeLock,
_space); _space);
} }
@@ -2599,7 +2599,7 @@ vm_set_area_protection(team_id team, area_id areaID, uint32 newProtection,
status_t status_t
vm_get_page_mapping(team_id team, addr_t vaddr, addr_t *paddr) 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) if (addressSpace == NULL)
return B_BAD_TEAM_ID; return B_BAD_TEAM_ID;
@@ -5021,8 +5021,8 @@ user_memset(void *s, char c, size_t count)
} }
long status_t
lock_memory(void *address, ulong numBytes, ulong flags) lock_memory_etc(team_id team, void *address, size_t numBytes, uint32 flags)
{ {
vm_address_space *addressSpace = NULL; vm_address_space *addressSpace = NULL;
struct vm_translation_map *map; struct vm_translation_map *map;
@@ -5032,9 +5032,12 @@ lock_memory(void *address, ulong numBytes, ulong flags)
bool isUser = IS_USER_ADDRESS(address); bool isUser = IS_USER_ADDRESS(address);
bool needsLocking = true; bool needsLocking = true;
if (isUser) if (isUser) {
addressSpace = vm_get_current_user_address_space(); if (team == B_CURRENT_TEAM)
else addressSpace = vm_get_current_user_address_space();
else
addressSpace = vm_get_address_space(team);
} else
addressSpace = vm_get_kernel_address_space(); addressSpace = vm_get_kernel_address_space();
if (addressSpace == NULL) if (addressSpace == NULL)
return B_ERROR; return B_ERROR;
@@ -5107,8 +5110,15 @@ out:
} }
long status_t
unlock_memory(void *address, ulong numBytes, ulong flags) 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; vm_address_space *addressSpace = NULL;
struct vm_translation_map *map; 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); addr_t base = ROUNDOWN(unalignedBase, B_PAGE_SIZE);
bool needsLocking = true; bool needsLocking = true;
if (IS_USER_ADDRESS(address)) if (IS_USER_ADDRESS(address)) {
addressSpace = vm_get_current_user_address_space(); if (team == B_CURRENT_TEAM)
else addressSpace = vm_get_current_user_address_space();
else
addressSpace = vm_get_address_space(team);
} else
addressSpace = vm_get_kernel_address_space(); addressSpace = vm_get_kernel_address_space();
if (addressSpace == NULL) if (addressSpace == NULL)
return B_ERROR; return B_ERROR;
@@ -5162,10 +5175,16 @@ out:
} }
/** According to the BeBook, this function should always succeed. status_t
* This is no longer the case. 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 long
get_memory_map(const void *address, ulong numBytes, physical_entry *table, get_memory_map(const void *address, ulong numBytes, physical_entry *table,
long numEntries) long numEntries)
@@ -5434,13 +5453,13 @@ clone_area(const char *name, void **_address, uint32 addressSpec,
area_id area_id
create_area_etc(struct team *team, const char *name, void **address, uint32 addressSpec, create_area_etc(team_id team, const char *name, void **address,
uint32 size, uint32 lock, uint32 protection) uint32 addressSpec, uint32 size, uint32 lock, uint32 protection)
{ {
fix_protection(&protection); fix_protection(&protection);
return vm_create_anonymous_area(team->id, (char *)name, address, return vm_create_anonymous_area(team, (char *)name, address, addressSpec,
addressSpec, size, lock, protection, false, true); 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 status_t
delete_area(area_id area) delete_area(area_id area)
{ {
+2 -2
View File
@@ -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. * Distributed under the terms of the MIT License.
* *
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@@ -166,7 +166,7 @@ delete_address_space(vm_address_space *addressSpace)
vm_address_space * vm_address_space *
vm_get_address_space_by_id(team_id id) vm_get_address_space(team_id id)
{ {
vm_address_space *addressSpace; vm_address_space *addressSpace;