-
From a1e6675fcbb598b8df358b87c85c7047a491a994 Mon Sep 17 00:00:00 2001
From: Hamish Morrison <hamish@lavabit.com>
Date: Wed, 15 Feb 2012 13:48:12 +0000
Subject: [PATCH] Add support for pthread_attr_(get/set)guardsize()
Adds pthread_attr_(get/set)guardsize() functions, adds a guardPages
parameter to create_area_etc() to support this, and updates all usages
of create_area_etc().
---
headers/posix/pthread.h | 9 ++--
headers/private/kernel/vm/vm.h | 2 +
headers/private/libroot/pthread_private.h | 1 +
headers/private/system/thread_defs.h | 14 +++----
.../kernel/bus_managers/scsi/dma_buffer.cpp | 2 +-
src/add-ons/kernel/bus_managers/scsi/emulation.cpp | 2 +-
src/libs/compat/freebsd_network/compat_cpp.cpp | 2 +-
.../arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp | 2 +-
src/system/kernel/arch/x86/arch_cpu.cpp | 2 +-
src/system/kernel/arch/x86/arch_int.cpp | 2 +-
.../arch/x86/paging/32bit/X86PagingMethod32Bit.cpp | 2 +-
.../arch/x86/paging/pae/X86PagingMethodPAE.cpp | 2 +-
src/system/kernel/arch/x86/vm86.cpp | 2 +-
src/system/kernel/debug/debug_heap.cpp | 2 +-
src/system/kernel/debug/tracing.cpp | 8 ++--
src/system/kernel/device_manager/dma_resources.cpp | 2 +-
src/system/kernel/elf.cpp | 2 +-
src/system/kernel/sem.cpp | 2 +-
src/system/kernel/slab/MemoryManager.cpp | 2 +-
src/system/kernel/team.cpp | 2 +-
src/system/kernel/thread.cpp | 44 +++++++++++--------
src/system/kernel/vm/vm.cpp | 27 +++++-------
src/system/libroot/posix/pthread/pthread.cpp | 4 +-
src/system/libroot/posix/pthread/pthread_attr.c | 28 ++++++++++++
24 files changed, 100 insertions(+), 67 deletions(-)
diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h
index cc5b900..ac84d62 100644
a
|
b
|
extern int pthread_attr_getschedparam(const pthread_attr_t *attr,
|
185 | 185 | extern int pthread_attr_setschedparam(pthread_attr_t *attr, |
186 | 186 | const struct sched_param *param); |
187 | 187 | |
| 188 | extern int pthread_attr_getguardsize(const pthread_attr_t *attr, |
| 189 | size_t *guardsize); |
| 190 | extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); |
| 191 | |
188 | 192 | #if 0 /* Unimplemented attribute functions: */ |
189 | 193 | |
190 | 194 | /* [TPS] */ |
… |
… |
extern int pthread_attr_getschedpolicy(const pthread_attr_t *attr,
|
196 | 200 | int *policy); |
197 | 201 | extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); |
198 | 202 | |
199 | | /* [XSI] */ |
200 | | extern int pthread_attr_getguardsize(const pthread_attr_t *attr, |
201 | | size_t *guardsize); |
202 | | extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); |
203 | | |
204 | 203 | /* [TSA] */ |
205 | 204 | extern int pthread_attr_getstackaddr(const pthread_attr_t *attr, |
206 | 205 | void **stackaddr); |
-
diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h
index 9163e3b..794766e 100644
a
|
b
|
void forbid_page_faults(void);
|
78 | 78 | // private kernel only extension (should be moved somewhere else): |
79 | 79 | area_id create_area_etc(team_id team, const char *name, uint32 size, |
80 | 80 | uint32 lock, uint32 protection, uint32 flags, |
| 81 | page_num_t guardPages, |
81 | 82 | const virtual_address_restrictions* virtualAddressRestrictions, |
82 | 83 | const physical_address_restrictions* physicalAddressRestrictions, |
83 | 84 | void **_address); |
… |
… |
status_t vm_reserve_address_range(team_id team, void **_address,
|
96 | 97 | uint32 addressSpec, addr_t size, uint32 flags); |
97 | 98 | area_id vm_create_anonymous_area(team_id team, const char* name, addr_t size, |
98 | 99 | uint32 wiring, uint32 protection, uint32 flags, |
| 100 | page_num_t guardPages, |
99 | 101 | const virtual_address_restrictions* virtualAddressRestrictions, |
100 | 102 | const physical_address_restrictions* physicalAddressRestrictions, |
101 | 103 | bool kernel, void** _address); |
-
diff --git a/headers/private/libroot/pthread_private.h b/headers/private/libroot/pthread_private.h
index f50bd28..1ddc00c 100644
a
|
b
|
typedef struct _pthread_attr {
|
40 | 40 | int32 detach_state; |
41 | 41 | int32 sched_priority; |
42 | 42 | size_t stack_size; |
| 43 | size_t guard_size; |
43 | 44 | } pthread_attr; |
44 | 45 | |
45 | 46 | typedef struct _pthread_rwlockattr { |
-
diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h
index 9f1b527..5153ec7 100644
a
|
b
|
|
12 | 12 | |
13 | 13 | |
14 | 14 | /** Size of the stack given to teams in user space */ |
15 | | #define USER_STACK_GUARD_PAGES 4 // 16 kB |
16 | | #define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024 \ |
17 | | - USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB |
18 | | #define USER_STACK_SIZE (256 * 1024 \ |
19 | | - USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 256 kB |
20 | | #define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB |
21 | | #define MAX_USER_STACK_SIZE (16 * 1024 * 1024 \ |
22 | | - USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB |
| 15 | #define USER_STACK_GUARD_PAGES 4 // 16 kB |
| 16 | #define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB |
| 17 | #define USER_STACK_SIZE (256 * 1024) // 256 kB |
| 18 | #define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB |
| 19 | #define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB |
23 | 20 | |
24 | 21 | |
25 | 22 | // The type of object a thread blocks on (thread::wait::type, set by |
… |
… |
struct thread_creation_attributes {
|
50 | 47 | void* args2; |
51 | 48 | void* stack_address; |
52 | 49 | size_t stack_size; |
| 50 | size_t guard_size; |
53 | 51 | pthread_t pthread; |
54 | 52 | uint32 flags; |
55 | 53 | }; |
-
diff --git a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp
index 9da56a5..1b32a1d 100644
a
|
b
|
scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)
|
195 | 195 | // TODO: Use 64 bit addresses, if possible! |
196 | 196 | #endif |
197 | 197 | buffer->area = create_area_etc(B_SYSTEM_TEAM, "DMA buffer", size, |
198 | | B_CONTIGUOUS, 0, 0, &virtualRestrictions, &physicalRestrictions, |
| 198 | B_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, &physicalRestrictions, |
199 | 199 | (void**)&buffer->address); |
200 | 200 | |
201 | 201 | if (buffer->area < 0) { |
-
diff --git a/src/add-ons/kernel/bus_managers/scsi/emulation.cpp b/src/add-ons/kernel/bus_managers/scsi/emulation.cpp
index 9127e24..161b273 100644
a
|
b
|
scsi_init_emulation_buffer(scsi_device_info *device, size_t buffer_size)
|
74 | 74 | physical_address_restrictions physicalRestrictions = {}; |
75 | 75 | physicalRestrictions.alignment = buffer_size; |
76 | 76 | device->buffer_area = create_area_etc(B_SYSTEM_TEAM, "ATAPI buffer", |
77 | | total_size, B_32_BIT_CONTIGUOUS, 0, 0, &virtualRestrictions, |
| 77 | total_size, B_32_BIT_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, |
78 | 78 | &physicalRestrictions, &address); |
79 | 79 | // TODO: Use B_CONTIGUOUS, if possible! |
80 | 80 | |
-
diff --git a/src/libs/compat/freebsd_network/compat_cpp.cpp b/src/libs/compat/freebsd_network/compat_cpp.cpp
index 97c9243..a9ae740 100644
a
|
b
|
_kernel_contigmalloc_cpp(const char* file, int line, size_t size,
|
37 | 37 | |
38 | 38 | void* address; |
39 | 39 | area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS, |
40 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, |
| 40 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0, |
41 | 41 | &virtualRestrictions, &physicalRestrictions, &address); |
42 | 42 | if (area < 0) |
43 | 43 | return NULL; |
-
diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp
index 9214286..b2d218f 100644
a
|
b
|
ARMPagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(
|
197 | 197 | physical_address_restrictions physicalRestrictions = {}; |
198 | 198 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
199 | 199 | PAGE_ALIGN(areaSize), B_FULL_LOCK, |
200 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 200 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
201 | 201 | &virtualRestrictions, &physicalRestrictions, &data); |
202 | 202 | if (dataArea < 0) |
203 | 203 | return dataArea; |
-
diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp
index 035c352..2be5bd2 100644
a
|
b
|
arch_cpu_init_post_vm(kernel_args *args)
|
753 | 753 | physical_address_restrictions physicalRestrictions = {}; |
754 | 754 | create_area_etc(B_SYSTEM_TEAM, "double fault stacks", |
755 | 755 | kDoubleFaultStackSize * smp_get_num_cpus(), B_FULL_LOCK, |
756 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 756 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
757 | 757 | &virtualRestrictions, &physicalRestrictions, |
758 | 758 | (void**)&sDoubleFaultStacks); |
759 | 759 | |
-
diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp
index 123f575..a0dc35b 100644
a
|
b
|
arch_int_init_post_vm(struct kernel_args *args)
|
873 | 873 | virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; |
874 | 874 | physical_address_restrictions physicalRestrictions = {}; |
875 | 875 | area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS, |
876 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 876 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
877 | 877 | &virtualRestrictions, &physicalRestrictions, (void**)&idt); |
878 | 878 | if (area < 0) |
879 | 879 | return area; |
-
diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp
index 9f84057..58cab87 100644
a
|
b
|
X86PagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(
|
195 | 195 | physical_address_restrictions physicalRestrictions = {}; |
196 | 196 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
197 | 197 | PAGE_ALIGN(areaSize), B_FULL_LOCK, |
198 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 198 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
199 | 199 | &virtualRestrictions, &physicalRestrictions, &data); |
200 | 200 | if (dataArea < 0) |
201 | 201 | return dataArea; |
-
diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp
index e7001bb..5136e77 100644
a
|
b
|
X86PagingMethodPAE::PhysicalPageSlotPool::AllocatePool(
|
486 | 486 | physical_address_restrictions physicalRestrictions = {}; |
487 | 487 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
488 | 488 | PAGE_ALIGN(areaSize), B_FULL_LOCK, |
489 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 489 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
490 | 490 | &virtualRestrictions, &physicalRestrictions, &data); |
491 | 491 | if (dataArea < 0) |
492 | 492 | return dataArea; |
-
diff --git a/src/system/kernel/arch/x86/vm86.cpp b/src/system/kernel/arch/x86/vm86.cpp
index ebfce51..39adf38 100644
a
|
b
|
vm86_prepare(struct vm86_state *state, unsigned int ramSize)
|
552 | 552 | virtualRestrictions.address_specification = B_EXACT_ADDRESS; |
553 | 553 | physical_address_restrictions physicalRestrictions = {}; |
554 | 554 | state->ram_area = create_area_etc(team->id, "dos", ramSize, B_NO_LOCK, |
555 | | B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions, |
| 555 | B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions, |
556 | 556 | &physicalRestrictions, &address); |
557 | 557 | if (state->ram_area < B_OK) { |
558 | 558 | ret = state->ram_area; |
-
diff --git a/src/system/kernel/debug/debug_heap.cpp b/src/system/kernel/debug/debug_heap.cpp
index 069e97d..326d865 100644
a
|
b
|
debug_heap_init()
|
296 | 296 | physical_address_restrictions physicalRestrictions = {}; |
297 | 297 | area_id area = create_area_etc(B_SYSTEM_TEAM, "kdebug heap", KDEBUG_HEAP, |
298 | 298 | B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
299 | | CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions, |
| 299 | CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, &physicalRestrictions, |
300 | 300 | (void**)&base); |
301 | 301 | if (area < 0) |
302 | 302 | return; |
-
diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp
index 72cbb95..5ae6d22 100644
a
|
b
|
TracingMetaData::Create(TracingMetaData*& _metaData)
|
435 | 435 | physical_address_restrictions physicalRestrictions = {}; |
436 | 436 | area = create_area_etc(B_SYSTEM_TEAM, "tracing log", |
437 | 437 | kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS, |
438 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 438 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
439 | 439 | &virtualRestrictions, &physicalRestrictions, |
440 | 440 | (void**)&metaData->fTraceOutputBuffer); |
441 | 441 | if (area < 0) |
… |
… |
TracingMetaData::_CreateMetaDataArea(bool findPrevious, area_id& _area,
|
486 | 486 | physicalRestrictions.high_address = metaDataAddress + B_PAGE_SIZE; |
487 | 487 | area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing metadata", |
488 | 488 | B_PAGE_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
489 | | CREATE_AREA_DONT_CLEAR, &virtualRestrictions, &physicalRestrictions, |
490 | | (void**)&metaData); |
| 489 | CREATE_AREA_DONT_CLEAR, 0, &virtualRestrictions, |
| 490 | &physicalRestrictions, (void**)&metaData); |
491 | 491 | if (area < 0) |
492 | 492 | continue; |
493 | 493 | |
… |
… |
TracingMetaData::_InitPreviousTracingData()
|
550 | 550 | + ROUNDUP(kTraceOutputBufferSize + MAX_TRACE_SIZE, B_PAGE_SIZE); |
551 | 551 | area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing log", |
552 | 552 | kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS, |
553 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, |
| 553 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, 0, |
554 | 554 | &virtualRestrictions, &physicalRestrictions, NULL); |
555 | 555 | if (area < 0) { |
556 | 556 | dprintf("Failed to init tracing meta data: Mapping tracing log " |
-
diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp
index 5c4b3de..190c952 100644
a
|
b
|
DMAResource::CreateBounceBuffer(DMABounceBuffer** _buffer)
|
246 | 246 | physicalRestrictions.alignment = fRestrictions.alignment; |
247 | 247 | physicalRestrictions.boundary = fRestrictions.boundary; |
248 | 248 | area = create_area_etc(B_SYSTEM_TEAM, "dma buffer", size, B_CONTIGUOUS, |
249 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, &virtualRestrictions, |
| 249 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, 0, &virtualRestrictions, |
250 | 250 | &physicalRestrictions, &bounceBuffer); |
251 | 251 | if (area < B_OK) |
252 | 252 | return area; |
-
diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp
index ad3c291..bdbf3fe 100644
a
|
b
|
elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
1931 | 1931 | virtualRestrictions.address_specification = B_EXACT_ADDRESS; |
1932 | 1932 | physical_address_restrictions physicalRestrictions = {}; |
1933 | 1933 | id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK, |
1934 | | B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions, |
| 1934 | B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions, |
1935 | 1935 | &physicalRestrictions, (void**)®ionAddress); |
1936 | 1936 | if (id < B_OK) { |
1937 | 1937 | dprintf("error allocating bss area: %s!\n", strerror(id)); |
-
diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp
index 2c460b9..6e6b26d 100644
a
|
b
|
haiku_sem_init(kernel_args *args)
|
431 | 431 | physical_address_restrictions physicalRestrictions = {}; |
432 | 432 | area = create_area_etc(B_SYSTEM_TEAM, "sem_table", |
433 | 433 | sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK, |
434 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 434 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
435 | 435 | &virtualRestrictions, &physicalRestrictions, (void**)&sSems); |
436 | 436 | if (area < 0) |
437 | 437 | panic("unable to allocate semaphore table!\n"); |
-
diff --git a/src/system/kernel/slab/MemoryManager.cpp b/src/system/kernel/slab/MemoryManager.cpp
index 3a6ac26..54523f9 100644
a
|
b
|
MemoryManager::AllocateRaw(size_t size, uint32 flags, void*& _pages)
|
628 | 628 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
629 | 629 | ((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0 |
630 | 630 | ? CREATE_AREA_DONT_WAIT : 0) |
631 | | | CREATE_AREA_DONT_CLEAR, |
| 631 | | CREATE_AREA_DONT_CLEAR, 0, |
632 | 632 | &virtualRestrictions, &physicalRestrictions, &_pages); |
633 | 633 | |
634 | 634 | status_t result = area >= 0 ? B_OK : area; |
-
diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp
index b794b07..346ae61 100644
a
|
b
|
create_team_user_data(Team* team)
|
1331 | 1331 | virtualRestrictions.address_specification = B_BASE_ADDRESS; |
1332 | 1332 | physical_address_restrictions physicalRestrictions = {}; |
1333 | 1333 | team->user_data_area = create_area_etc(team->id, "user area", size, |
1334 | | B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions, |
| 1334 | B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions, |
1335 | 1335 | &physicalRestrictions, &address); |
1336 | 1336 | if (team->user_data_area < 0) |
1337 | 1337 | return team->user_data_area; |
-
diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index e6567a1..bc903bf 100644
a
|
b
|
init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)
|
781 | 781 | |
782 | 782 | static status_t |
783 | 783 | create_thread_user_stack(Team* team, Thread* thread, void* _stackBase, |
784 | | size_t stackSize, size_t additionalSize, char* nameBuffer) |
| 784 | size_t stackSize, size_t additionalSize, size_t guardSize, |
| 785 | char* nameBuffer) |
785 | 786 | { |
786 | 787 | area_id stackArea = -1; |
787 | 788 | uint8* stackBase = (uint8*)_stackBase; |
788 | 789 | |
789 | 790 | if (stackBase != NULL) { |
790 | 791 | // A stack has been specified. It must be large enough to hold the |
791 | | // TLS space at least. |
| 792 | // TLS space at least. Guard pages are ignored for existing stacks. |
792 | 793 | STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE); |
793 | 794 | if (stackSize < MIN_USER_STACK_SIZE) |
794 | 795 | return B_BAD_VALUE; |
795 | | |
796 | | stackBase -= TLS_SIZE; |
797 | | } |
798 | | |
799 | | if (stackBase == NULL) { |
| 796 | } else { |
800 | 797 | // No user-defined stack -- allocate one. For non-main threads the stack |
801 | 798 | // will be between USER_STACK_REGION and the main thread stack area. For |
802 | 799 | // a main thread the position is fixed. |
803 | 800 | |
| 801 | guardSize = PAGE_ALIGN(guardSize); |
| 802 | page_num_t guardPages = guardSize / B_PAGE_SIZE; |
| 803 | |
804 | 804 | if (stackSize == 0) { |
805 | 805 | // Use the default size (a different one for a main thread). |
806 | 806 | stackSize = thread->id == team->id |
807 | 807 | ? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE; |
808 | 808 | } else { |
809 | 809 | // Verify that the given stack size is large enough. |
810 | | if (stackSize < MIN_USER_STACK_SIZE - TLS_SIZE) |
| 810 | if (stackSize < MIN_USER_STACK_SIZE) |
811 | 811 | return B_BAD_VALUE; |
812 | 812 | |
813 | 813 | stackSize = PAGE_ALIGN(stackSize); |
814 | 814 | } |
815 | | stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE; |
816 | 815 | |
817 | | size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize); |
| 816 | size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE |
| 817 | + additionalSize); |
818 | 818 | |
819 | 819 | snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%ld_stack", thread->name, |
820 | 820 | thread->id); |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
838 | 838 | |
839 | 839 | stackArea = create_area_etc(team->id, nameBuffer, |
840 | 840 | areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, |
841 | | 0, &virtualRestrictions, &physicalRestrictions, |
| 841 | 0, guardPages, &virtualRestrictions, &physicalRestrictions, |
842 | 842 | (void**)&stackBase); |
843 | 843 | if (stackArea < 0) |
844 | 844 | return stackArea; |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
846 | 846 | |
847 | 847 | // set the stack |
848 | 848 | ThreadLocker threadLocker(thread); |
849 | | thread->user_stack_base = (addr_t)stackBase; |
| 849 | thread->user_stack_base = (addr_t)stackBase + guardSize; |
850 | 850 | thread->user_stack_size = stackSize; |
851 | 851 | thread->user_stack_area = stackArea; |
852 | 852 | |
… |
… |
thread_create_user_stack(Team* team, Thread* thread, void* stackBase,
|
860 | 860 | { |
861 | 861 | char nameBuffer[B_OS_NAME_LENGTH]; |
862 | 862 | return create_thread_user_stack(team, thread, stackBase, stackSize, |
863 | | additionalSize, nameBuffer); |
| 863 | additionalSize, USER_STACK_GUARD_PAGES * B_PAGE_SIZE, nameBuffer); |
864 | 864 | } |
865 | 865 | |
866 | 866 | |
… |
… |
thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
|
917 | 917 | char stackName[B_OS_NAME_LENGTH]; |
918 | 918 | snprintf(stackName, B_OS_NAME_LENGTH, "%s_%ld_kstack", thread->name, |
919 | 919 | thread->id); |
920 | | thread->kernel_stack_area = create_area(stackName, |
921 | | (void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS, |
922 | | KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, |
923 | | B_FULL_LOCK, |
924 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA); |
| 920 | virtual_address_restrictions virtualRestrictions = {}; |
| 921 | virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; |
| 922 | physical_address_restrictions physicalRestrictions = {}; |
| 923 | |
| 924 | thread->kernel_stack_area = create_area_etc(B_SYSTEM_TEAM, stackName, |
| 925 | KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, |
| 926 | B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA |
| 927 | | B_KERNEL_STACK_AREA, 0, KERNEL_STACK_GUARD_PAGES, |
| 928 | &virtualRestrictions, &physicalRestrictions, |
| 929 | (void**)&thread->kernel_stack_base); |
925 | 930 | |
926 | 931 | if (thread->kernel_stack_area < 0) { |
927 | 932 | // we're not yet part of a team, so we can just bail out |
… |
… |
thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
|
950 | 955 | if (thread->user_stack_base == 0) { |
951 | 956 | status = create_thread_user_stack(team, thread, |
952 | 957 | attributes.stack_address, attributes.stack_size, |
953 | | attributes.additional_stack_size, stackName); |
| 958 | attributes.additional_stack_size, attributes.guard_size, |
| 959 | stackName); |
954 | 960 | if (status != B_OK) |
955 | 961 | return status; |
956 | 962 | } |
-
diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
index c6d6829..2ffdc8f 100644
a
|
b
|
vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec,
|
1177 | 1177 | |
1178 | 1178 | area_id |
1179 | 1179 | vm_create_anonymous_area(team_id team, const char *name, addr_t size, |
1180 | | uint32 wiring, uint32 protection, uint32 flags, |
| 1180 | uint32 wiring, uint32 protection, uint32 flags, page_num_t guardPages, |
1181 | 1181 | const virtual_address_restrictions* virtualAddressRestrictions, |
1182 | 1182 | const physical_address_restrictions* physicalAddressRestrictions, |
1183 | 1183 | bool kernel, void** _address) |
… |
… |
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
1186 | 1186 | VMCache* cache; |
1187 | 1187 | vm_page* page = NULL; |
1188 | 1188 | bool isStack = (protection & B_STACK_AREA) != 0; |
1189 | | page_num_t guardPages; |
1190 | 1189 | bool canOvercommit = false; |
1191 | 1190 | uint32 pageAllocFlags = (flags & CREATE_AREA_DONT_CLEAR) == 0 |
1192 | 1191 | ? VM_PAGE_ALLOC_CLEAR : 0; |
… |
… |
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
1195 | 1194 | |
1196 | 1195 | size = PAGE_ALIGN(size); |
1197 | 1196 | |
1198 | | if (size == 0) |
| 1197 | if (size == 0 || size < guardPages * B_PAGE_SIZE) |
1199 | 1198 | return B_BAD_VALUE; |
1200 | 1199 | if (!arch_vm_supports_protection(protection)) |
1201 | 1200 | return B_NOT_SUPPORTED; |
… |
… |
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
1371 | 1370 | |
1372 | 1371 | // create an anonymous cache |
1373 | 1372 | // if it's a stack, make sure that two pages are available at least |
1374 | | guardPages = isStack ? ((protection & B_USER_PROTECTION) != 0 |
1375 | | ? USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0; |
1376 | 1373 | status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit, |
1377 | 1374 | isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages, |
1378 | 1375 | wiring == B_NO_LOCK, priority); |
… |
… |
_vm_map_file(team_id team, const char* name, void** _address,
|
1876 | 1873 | virtualRestrictions.address_specification = addressSpec; |
1877 | 1874 | physical_address_restrictions physicalRestrictions = {}; |
1878 | 1875 | return vm_create_anonymous_area(team, name, size, B_NO_LOCK, protection, |
1879 | | flags, &virtualRestrictions, &physicalRestrictions, kernel, |
| 1876 | flags, 0, &virtualRestrictions, &physicalRestrictions, kernel, |
1880 | 1877 | _address); |
1881 | 1878 | } |
1882 | 1879 | |
… |
… |
vm_init(kernel_args* args)
|
3886 | 3883 | create_area_etc(VMAddressSpace::KernelID(), "cache info table", |
3887 | 3884 | ROUNDUP(kCacheInfoTableCount * sizeof(cache_info), B_PAGE_SIZE), |
3888 | 3885 | B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
3889 | | CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions, |
3890 | | (void**)&sCacheInfoTable); |
| 3886 | CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, |
| 3887 | &physicalRestrictions, (void**)&sCacheInfoTable); |
3891 | 3888 | } |
3892 | 3889 | #endif // DEBUG_CACHE_LIST |
3893 | 3890 | |
… |
… |
clone_area(const char* name, void** _address, uint32 addressSpec,
|
5854 | 5851 | |
5855 | 5852 | area_id |
5856 | 5853 | create_area_etc(team_id team, const char* name, uint32 size, uint32 lock, |
5857 | | uint32 protection, uint32 flags, |
| 5854 | uint32 protection, uint32 flags, page_num_t guardPages, |
5858 | 5855 | const virtual_address_restrictions* virtualAddressRestrictions, |
5859 | 5856 | const physical_address_restrictions* physicalAddressRestrictions, |
5860 | 5857 | void** _address) |
… |
… |
create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
|
5862 | 5859 | fix_protection(&protection); |
5863 | 5860 | |
5864 | 5861 | return vm_create_anonymous_area(team, name, size, lock, protection, flags, |
5865 | | virtualAddressRestrictions, physicalAddressRestrictions, true, |
5866 | | _address); |
| 5862 | guardPages, virtualAddressRestrictions, physicalAddressRestrictions, |
| 5863 | true, _address); |
5867 | 5864 | } |
5868 | 5865 | |
5869 | 5866 | |
… |
… |
__create_area_haiku(const char* name, void** _address, uint32 addressSpec,
|
5878 | 5875 | virtualRestrictions.address_specification = addressSpec; |
5879 | 5876 | physical_address_restrictions physicalRestrictions = {}; |
5880 | 5877 | return vm_create_anonymous_area(VMAddressSpace::KernelID(), name, size, |
5881 | | lock, protection, 0, &virtualRestrictions, &physicalRestrictions, true, |
5882 | | _address); |
| 5878 | lock, protection, 0, 0, &virtualRestrictions, &physicalRestrictions, |
| 5879 | true, _address); |
5883 | 5880 | } |
5884 | 5881 | |
5885 | 5882 | |
… |
… |
_user_create_area(const char* userName, void** userAddress, uint32 addressSpec,
|
6122 | 6119 | virtualRestrictions.address_specification = addressSpec; |
6123 | 6120 | physical_address_restrictions physicalRestrictions = {}; |
6124 | 6121 | area_id area = vm_create_anonymous_area(VMAddressSpace::CurrentID(), name, |
6125 | | size, lock, protection, 0, &virtualRestrictions, &physicalRestrictions, |
6126 | | false, &address); |
| 6122 | size, lock, protection, 0, 0, &virtualRestrictions, |
| 6123 | &physicalRestrictions, false, &address); |
6127 | 6124 | |
6128 | 6125 | if (area >= B_OK |
6129 | 6126 | && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) { |
-
diff --git a/src/system/libroot/posix/pthread/pthread.cpp b/src/system/libroot/posix/pthread/pthread.cpp
index 4c5104a..e8f1b61 100644
a
|
b
|
|
25 | 25 | static const pthread_attr pthread_attr_default = { |
26 | 26 | PTHREAD_CREATE_JOINABLE, |
27 | 27 | B_NORMAL_PRIORITY, |
28 | | USER_STACK_SIZE |
| 28 | USER_STACK_SIZE, |
| 29 | USER_STACK_GUARD_PAGES * B_PAGE_SIZE |
29 | 30 | }; |
30 | 31 | |
31 | 32 | |
… |
… |
__pthread_init_creation_attributes(const pthread_attr_t* pthreadAttributes,
|
117 | 118 | attributes->args2 = argument2; |
118 | 119 | attributes->stack_address = NULL; |
119 | 120 | attributes->stack_size = attr->stack_size; |
| 121 | attributes->guard_size = attr->guard_size; |
120 | 122 | attributes->pthread = thread; |
121 | 123 | attributes->flags = 0; |
122 | 124 | |
-
diff --git a/src/system/libroot/posix/pthread/pthread_attr.c b/src/system/libroot/posix/pthread/pthread_attr.c
index 3054690..8252fae 100644
a
|
b
|
pthread_attr_init(pthread_attr_t *_attr)
|
30 | 30 | attr->detach_state = PTHREAD_CREATE_JOINABLE; |
31 | 31 | attr->sched_priority = B_NORMAL_PRIORITY; |
32 | 32 | attr->stack_size = USER_STACK_SIZE; |
| 33 | attr->guard_size = USER_STACK_GUARD_PAGES * B_PAGE_SIZE; |
33 | 34 | |
34 | 35 | *_attr = attr; |
35 | 36 | return B_OK; |
… |
… |
pthread_attr_getschedparam(const pthread_attr_t *attr,
|
162 | 163 | return 0; |
163 | 164 | } |
164 | 165 | |
| 166 | |
| 167 | int |
| 168 | pthread_attr_getguardsize(const pthread_attr_t *_attr, size_t *guardsize) |
| 169 | { |
| 170 | pthread_attr *attr; |
| 171 | |
| 172 | if (_attr == NULL || (attr = *_attr) == NULL || guardsize == NULL) |
| 173 | return B_BAD_VALUE; |
| 174 | |
| 175 | *guardsize = attr->guard_size; |
| 176 | |
| 177 | return 0; |
| 178 | } |
| 179 | |
| 180 | |
| 181 | int |
| 182 | pthread_attr_setguardsize(pthread_attr_t *_attr, size_t guardsize) |
| 183 | { |
| 184 | pthread_attr *attr; |
| 185 | |
| 186 | if (_attr == NULL || (attr = *_attr) == NULL) |
| 187 | return B_BAD_VALUE; |
| 188 | |
| 189 | attr->guard_size = guardsize; |
| 190 | |
| 191 | return 0; |
| 192 | } |