diff --git a/headers/private/kernel/vm.h b/headers/private/kernel/vm.h index e82da57dd3..d56c56db25 100644 --- a/headers/private/kernel/vm.h +++ b/headers/private/kernel/vm.h @@ -56,7 +56,7 @@ void forbid_page_faults(void); // private kernel only extension (should be moved somewhere else): area_id create_area_etc(team_id team, const char *name, void **address, uint32 addressSpec, uint32 size, uint32 lock, uint32 protection, - uint32 flags); + addr_t physicalAddress, uint32 flags); area_id transfer_area(area_id id, void** _address, uint32 addressSpec, team_id target, bool kernel); @@ -65,7 +65,7 @@ status_t vm_reserve_address_range(team_id team, void **_address, uint32 addressSpec, addr_t size, uint32 flags); area_id vm_create_anonymous_area(team_id team, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 wiring, uint32 protection, - uint32 flags, bool kernel); + addr_t physicalAddress, uint32 flags, bool kernel); area_id vm_map_physical_memory(team_id team, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 protection, addr_t phys_addr); area_id vm_map_file(team_id aid, const char *name, void **address, diff --git a/src/system/kernel/arch/x86/vm86.cpp b/src/system/kernel/arch/x86/vm86.cpp index 27bd53b0a5..7ae705df67 100644 --- a/src/system/kernel/arch/x86/vm86.cpp +++ b/src/system/kernel/arch/x86/vm86.cpp @@ -548,7 +548,7 @@ vm86_prepare(struct vm86_state *state, unsigned int ramSize) void *address = (void *)0; state->ram_area = create_area_etc(team->id, "dos", &address, - B_EXACT_ADDRESS, ramSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0); + B_EXACT_ADDRESS, ramSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0); if (state->ram_area < B_OK) { ret = state->ram_area; TRACE("Could not create RAM area\n"); diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index 8faf8591e2..e23dc4b59d 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -1834,7 +1834,7 @@ elf_load_user_image(const char *path, struct team *team, int flags, regionAddress += fileUpperBound; id = create_area_etc(team->id, regionName, (void **)®ionAddress, B_EXACT_ADDRESS, bssSize, - B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0); + B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0); if (id < B_OK) { dprintf("error allocating bss area: %s!\n", strerror(id)); status = B_NOT_AN_EXECUTABLE; diff --git a/src/system/kernel/slab/Slab.cpp b/src/system/kernel/slab/Slab.cpp index be4e810481..629cb08d2a 100644 --- a/src/system/kernel/slab/Slab.cpp +++ b/src/system/kernel/slab/Slab.cpp @@ -463,10 +463,10 @@ area_allocate_pages(object_cache *cache, void **pages, uint32 flags, // if we are allocating, it is because we need the pages immediatly // so we lock them. when moving the slab to the empty list we should // unlock them, and lock them again when getting one from the empty list. - area_id areaId = vm_create_anonymous_area(vm_kernel_address_space_id(), + area_id areaId = create_area_etc(vm_kernel_address_space_id(), cache->name, pages, addressSpec, cache->slab_size, lock, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - (flags & CACHE_DONT_SLEEP) != 0 ? CREATE_AREA_DONT_WAIT : 0, true); + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, + (flags & CACHE_DONT_SLEEP) != 0 ? CREATE_AREA_DONT_WAIT : 0); if (unlockWhileAllocating) cache->Lock(); diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 2440854f63..2d6b66649c 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -853,7 +853,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->id, "user area", &address, - B_BASE_ADDRESS, size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0); + B_BASE_ADDRESS, size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0); if (team->user_data_area < 0) return team->user_data_area; @@ -1033,7 +1033,7 @@ team_create_thread_start(void *args) sprintf(ustack_name, "%s_main_stack", team->name); 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, 0); + B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, 0, 0); if (t->user_stack_area < 0) { dprintf("team_create_thread_start: could not create default user stack " "region: %s\n", strerror(t->user_stack_area)); diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 685b78ee78..a5c3ed7333 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -559,7 +559,7 @@ create_thread(thread_creation_attributes& attributes, bool kernel) 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, 0); + B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, 0, 0); if (thread->user_stack_area < B_OK || arch_thread_init_tls(thread) < B_OK) { // great, we have a fully running thread without a (usable) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 7f7f2437b5..eb5cb5c9c9 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -1759,7 +1759,7 @@ vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec, area_id vm_create_anonymous_area(team_id team, const char* name, void** address, uint32 addressSpec, addr_t size, uint32 wiring, uint32 protection, - uint32 flags, bool kernel) + addr_t physicalAddress, uint32 flags, bool kernel) { vm_area* area; vm_cache* cache; @@ -1767,7 +1767,6 @@ vm_create_anonymous_area(team_id team, const char* name, void** address, bool isStack = (protection & B_STACK_AREA) != 0; page_num_t guardPages; bool canOvercommit = false; - addr_t physicalBase = 0; uint32 newPageState = (flags & CREATE_AREA_DONT_CLEAR) != 0 ? PAGE_STATE_FREE : PAGE_STATE_CLEAR; @@ -1797,15 +1796,17 @@ vm_create_anonymous_area(team_id team, const char* name, void** address, case B_ANY_KERNEL_BLOCK_ADDRESS: break; case B_PHYSICAL_BASE_ADDRESS: - physicalBase = (addr_t)*address; + physicalAddress = (addr_t)*address; addressSpec = B_ANY_KERNEL_ADDRESS; - wiring = B_CONTIGUOUS; break; default: return B_BAD_VALUE; } + if (physicalAddress != 0) + wiring = B_CONTIGUOUS; + bool doReserveMemory = false; switch (wiring) { case B_NO_LOCK: @@ -1887,7 +1888,7 @@ vm_create_anonymous_area(team_id team, const char* name, void** address, if (wiring == B_CONTIGUOUS) { // we try to allocate the page run here upfront as this may easily // fail for obvious reasons - page = vm_page_allocate_page_run(newPageState, physicalBase, + page = vm_page_allocate_page_run(newPageState, physicalAddress, size / B_PAGE_SIZE); if (page == NULL) { status = B_NO_MEMORY; @@ -2276,7 +2277,7 @@ _vm_map_file(team_id team, const char* name, void** _address, if (fd < 0) { uint32 flags = unmapAddressRange ? CREATE_AREA_UNMAP_ADDRESS_RANGE : 0; return vm_create_anonymous_area(team, name, _address, addressSpec, size, - B_NO_LOCK, protection, flags, kernel); + B_NO_LOCK, protection, 0, flags, kernel); } // get the open flags of the FD @@ -5877,12 +5878,12 @@ clone_area(const char* name, void** _address, uint32 addressSpec, area_id create_area_etc(team_id team, const char* name, void** address, uint32 addressSpec, uint32 size, uint32 lock, uint32 protection, - uint32 flags) + addr_t physicalAddress, uint32 flags) { fix_protection(&protection); return vm_create_anonymous_area(team, (char*)name, address, addressSpec, - size, lock, protection, flags, true); + size, lock, protection, physicalAddress, flags, true); } @@ -5893,7 +5894,7 @@ create_area(const char* name, void** _address, uint32 addressSpec, size_t size, fix_protection(&protection); return vm_create_anonymous_area(vm_kernel_address_space_id(), (char*)name, - _address, addressSpec, size, lock, protection, 0, true); + _address, addressSpec, size, lock, protection, 0, 0, true); } @@ -6131,7 +6132,8 @@ _user_create_area(const char* userName, void** userAddress, uint32 addressSpec, fix_protection(&protection); area_id area = vm_create_anonymous_area(vm_current_user_address_space_id(), - (char*)name, &address, addressSpec, size, lock, protection, 0, false); + (char*)name, &address, addressSpec, size, lock, protection, 0, 0, + false); if (area >= B_OK && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) {